2 * ustp - OpenWrt STP/RSTP/MSTP daemon
3 * Copyright (C) 2021 Felix Fietkau <nbd@nbd.name>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
18 #include <libubox/uloop.h>
19 #include <libubox/utils.h>
22 #include "bridge_ctl.h"
23 #include "bridge_track.h"
26 static pthread_t w_thread
;
27 static pthread_mutex_t w_lock
= PTHREAD_MUTEX_INITIALIZER
;
28 static pthread_cond_t w_cond
= PTHREAD_COND_INITIALIZER
;
29 static LIST_HEAD(w_queue
);
30 static struct uloop_timeout w_timer
;
32 struct worker_queued_event
{
33 struct list_head list
;
34 struct worker_event ev
;
37 static struct worker_event
*worker_next_event(void)
39 struct worker_queued_event
*ev
;
40 static struct worker_event ev_data
;
42 pthread_mutex_lock(&w_lock
);
43 while (list_empty(&w_queue
))
44 pthread_cond_wait(&w_cond
, &w_lock
);
46 ev
= list_first_entry(&w_queue
, struct worker_queued_event
, list
);
48 pthread_mutex_unlock(&w_lock
);
50 memcpy(&ev_data
, &ev
->ev
, sizeof(ev_data
));
57 handle_worker_event(struct worker_event
*ev
)
60 case WORKER_EV_ONE_SECOND
:
63 case WORKER_EV_BRIDGE_EVENT
:
64 bridge_event_handler();
66 case WORKER_EV_RECV_PACKET
:
69 case WORKER_EV_BRIDGE_ADD
:
70 bridge_create(ev
->bridge_idx
, &ev
->bridge_config
);
72 case WORKER_EV_BRIDGE_REMOVE
:
73 bridge_delete(ev
->bridge_idx
);
80 static void *worker_thread_fn(void *arg
)
82 struct worker_event
*ev
;
85 ev
= worker_next_event();
86 if (ev
->type
== WORKER_EV_SHUTDOWN
)
89 handle_worker_event(ev
);
95 static void worker_timer_cb(struct uloop_timeout
*t
)
97 struct worker_event ev
= {
98 .type
= WORKER_EV_ONE_SECOND
,
101 uloop_timeout_set(t
, 1000);
102 worker_queue_event(&ev
);
105 int worker_init(void)
107 w_timer
.cb
= worker_timer_cb
;
108 uloop_timeout_set(&w_timer
, 1000);
110 return pthread_create(&w_thread
, NULL
, worker_thread_fn
, NULL
);
113 void worker_cleanup(void)
115 struct worker_event ev
= {
116 .type
= WORKER_EV_SHUTDOWN
,
119 worker_queue_event(&ev
);
120 pthread_join(w_thread
, NULL
);
123 void worker_queue_event(struct worker_event
*ev
)
125 struct worker_queued_event
*evc
;
127 evc
= malloc(sizeof(*evc
));
128 memcpy(&evc
->ev
, ev
, sizeof(*ev
));
130 pthread_mutex_lock(&w_lock
);
131 list_add_tail(&evc
->list
, &w_queue
);
132 pthread_mutex_unlock(&w_lock
);
134 pthread_cond_signal(&w_cond
);