• 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                               ev->bridge_priority);
 72                 break;
 73         case WORKER_EV_BRIDGE_REMOVE:
 74                 bridge_delete(ev->bridge_idx);
 75                 break;
 76         default:
 77                 return;
 78         }
 79 }
 80 
 81 static void *worker_thread_fn(void *arg)
 82 {
 83         struct worker_event *ev;
 84 
 85         while (1) {
 86                 ev = worker_next_event();
 87                 if (ev->type == WORKER_EV_SHUTDOWN)
 88                         break;
 89 
 90                 handle_worker_event(ev);
 91         }
 92 
 93         return NULL;
 94 }
 95 
 96 static void worker_timer_cb(struct uloop_timeout *t)
 97 {
 98         struct worker_event ev = {
 99                 .type = WORKER_EV_ONE_SECOND,
100         };
101 
102         uloop_timeout_set(t, 1000);
103         worker_queue_event(&ev);
104 }
105 
106 int worker_init(void)
107 {
108         w_timer.cb = worker_timer_cb;
109         uloop_timeout_set(&w_timer, 1000);
110 
111         return pthread_create(&w_thread, NULL, worker_thread_fn, NULL);
112 }
113 
114 void worker_cleanup(void)
115 {
116         struct worker_event ev = {
117                 .type = WORKER_EV_SHUTDOWN,
118         };
119 
120         worker_queue_event(&ev);
121         pthread_join(w_thread, NULL);
122 }
123 
124 void worker_queue_event(struct worker_event *ev)
125 {
126         struct worker_queued_event *evc;
127 
128         evc = malloc(sizeof(*evc));
129         memcpy(&evc->ev, ev, sizeof(*ev));
130 
131         pthread_mutex_lock(&w_lock);
132         list_add_tail(&evc->list, &w_queue);
133         pthread_mutex_unlock(&w_lock);
134 
135         pthread_cond_signal(&w_cond);
136 }
137 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt