• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ustp/worker.c

  1 /*
  2  * ustp - OpenWrt STP/RSTP/MSTP daemon
  3  * Copyright (C) 2021 Felix Fietkau <nbd@nbd.name>
  4  *
  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
  8  *
  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.
 13  */
 14 #include <pthread.h>
 15 #include <string.h>
 16 #include <stdlib.h>
 17 
 18 #include <libubox/uloop.h>
 19 #include <libubox/utils.h>
 20 
 21 #include "worker.h"
 22 #include "bridge_ctl.h"
 23 #include "bridge_track.h"
 24 #include "packet.h"
 25 
 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;
 31 
 32 struct worker_queued_event {
 33         struct list_head list;
 34         struct worker_event ev;
 35 };
 36 
 37 static struct worker_event *worker_next_event(void)
 38 {
 39         struct worker_queued_event *ev;
 40         static struct worker_event ev_data;
 41 
 42         pthread_mutex_lock(&w_lock);
 43         while (list_empty(&w_queue))
 44                 pthread_cond_wait(&w_cond, &w_lock);
 45 
 46         ev = list_first_entry(&w_queue, struct worker_queued_event, list);
 47         list_del(&ev->list);
 48         pthread_mutex_unlock(&w_lock);
 49 
 50         memcpy(&ev_data, &ev->ev, sizeof(ev_data));
 51         free(ev);
 52 
 53         return &ev_data;
 54 }
 55 
 56 static void
 57 handle_worker_event(struct worker_event *ev)
 58 {
 59         switch (ev->type) {
 60         case WORKER_EV_ONE_SECOND:
 61                 bridge_one_second();
 62                 break;
 63         case WORKER_EV_BRIDGE_EVENT:
 64                 bridge_event_handler();
 65                 break;
 66         case WORKER_EV_RECV_PACKET:
 67                 packet_rcv();
 68                 break;
 69         case WORKER_EV_BRIDGE_ADD:
 70                 bridge_create(ev->bridge_idx, &ev->bridge_config);
 71                 break;
 72         case WORKER_EV_BRIDGE_REMOVE:
 73                 bridge_delete(ev->bridge_idx);
 74                 break;
 75         default:
 76                 return;
 77         }
 78 }
 79 
 80 static void *worker_thread_fn(void *arg)
 81 {
 82         struct worker_event *ev;
 83 
 84         while (1) {
 85                 ev = worker_next_event();
 86                 if (ev->type == WORKER_EV_SHUTDOWN)
 87                         break;
 88 
 89                 handle_worker_event(ev);
 90         }
 91 
 92         return NULL;
 93 }
 94 
 95 static void worker_timer_cb(struct uloop_timeout *t)
 96 {
 97         struct worker_event ev = {
 98                 .type = WORKER_EV_ONE_SECOND,
 99         };
100 
101         uloop_timeout_set(t, 1000);
102         worker_queue_event(&ev);
103 }
104 
105 int worker_init(void)
106 {
107         w_timer.cb = worker_timer_cb;
108         uloop_timeout_set(&w_timer, 1000);
109 
110         return pthread_create(&w_thread, NULL, worker_thread_fn, NULL);
111 }
112 
113 void worker_cleanup(void)
114 {
115         struct worker_event ev = {
116                 .type = WORKER_EV_SHUTDOWN,
117         };
118 
119         worker_queue_event(&ev);
120         pthread_join(w_thread, NULL);
121 }
122 
123 void worker_queue_event(struct worker_event *ev)
124 {
125         struct worker_queued_event *evc;
126 
127         evc = malloc(sizeof(*evc));
128         memcpy(&evc->ev, ev, sizeof(*ev));
129 
130         pthread_mutex_lock(&w_lock);
131         list_add_tail(&evc->list, &w_queue);
132         pthread_mutex_unlock(&w_lock);
133 
134         pthread_cond_signal(&w_cond);
135 }
136 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt