libamxp  1.4.0
Patterns C Implementation
amxp_signal.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <amxc/amxc.h>
#include <amxp/amxp.h>
#include "amxp_signal_priv.h"

Go to the source code of this file.

Data Structures

struct  _signal_ctrl
 
struct  _signal_queue_item
 

Macros

#define _GNU_SOURCE
 

Typedefs

typedef struct _signal_ctrl signal_ctrl_t
 
typedef struct _signal_queue_item signal_queue_item_t
 

Functions

static int amxp_signal_queue_lock (void)
 
static int amxp_signal_queue_unlock (void)
 
void amxp_free_slots (amxc_llist_it_t *it)
 
static void amxp_free_signals (UNUSED const char *key, amxc_htable_it_t *it)
 
static void amxp_free_queued_signals (amxc_lqueue_it_t *it)
 
static int amxp_signal_queue (const amxp_signal_t *const signal, const amxc_var_t *const data)
 
static int amxp_deferred_queue (amxp_signal_mngr_t *sigmngr, amxp_deferred_fn_t fn, const amxc_var_t *const data, void *priv)
 
static signal_queue_item_tamxp_signal_dequeue (void)
 
static int amxp_signal_create_pipe (void)
 
static void amxp_slot_trigger (const amxp_slot_t *const slot, const char *name, const amxc_var_t *const data)
 
static void amxp_sigmngr_trigger_regexp (amxp_signal_mngr_t *sig_mngr, const char *name, const amxc_var_t *const data)
 
static void amxp_signal_garbage_collect (amxp_signal_t *signal)
 
static void amxp_sigmngr_garbage_collect (amxp_signal_mngr_t *sig_mngr)
 
amxp_signal_mngr_tamxp_get_sigmngr (amxp_signal_mngr_t *sig_mngr)
 
void amxp_get_sigmngrs (amxc_llist_t **sigmngrs, amxc_llist_t **pending_sigmngrs)
 
const amxc_htable_t * amxp_get_signals (const amxp_signal_mngr_t *sig_mngr)
 
int amxp_sigmngr_new (amxp_signal_mngr_t **sig_mngr)
 Constructor function, creates a new signal manager instance. More...
 
int amxp_sigmngr_delete (amxp_signal_mngr_t **sig_mngr)
 Destructor function, deletes a signal manager instance. More...
 
int amxp_sigmngr_init (amxp_signal_mngr_t *sig_mngr)
 Initializing function, initializes members of the amxp_signal_mngr_t structure. More...
 
int amxp_sigmngr_clean (amxp_signal_mngr_t *sig_mngr)
 Clean-up functions, cleans-up all members of a amxp_signal_mngr_t structure. More...
 
int amxp_sigmngr_add_signal (amxp_signal_mngr_t *const sig_mngr, const char *name)
 Adds a signal to a signal manager. More...
 
int amxp_sigmngr_remove_signal (amxp_signal_mngr_t *const sig_mngr, const char *name)
 Removes a signal from a signal manager. More...
 
amxp_signal_tamxp_sigmngr_find_signal (const amxp_signal_mngr_t *const sig_mngr, const char *name)
 Get the pointer to the signal. More...
 
void amxp_sigmngr_trigger_signal (amxp_signal_mngr_t *const sig_mngr, const char *name, const amxc_var_t *const data)
 Triggers a signal. More...
 
int amxp_sigmngr_emit_signal (const amxp_signal_mngr_t *const sig_mngr, const char *name, const amxc_var_t *const data)
 Emits a signal. More...
 
int amxp_sigmngr_deferred_call (amxp_signal_mngr_t *const sig_mngr, amxp_deferred_fn_t fn, const amxc_var_t *const data, void *priv)
 Defers a function call. More...
 
int amxp_sigmngr_enable (amxp_signal_mngr_t *const sig_mngr, bool enable)
 Enables or disables the signal manager. More...
 
int amxp_sigmngr_suspend (amxp_signal_mngr_t *const sig_mngr)
 Suspends the handling of signals for the signal manager. More...
 
int amxp_sigmngr_resume (amxp_signal_mngr_t *const sig_mngr)
 Resumes the handling of signals for the signal manager. More...
 
int amxp_signal_new (amxp_signal_mngr_t *sig_mngr, amxp_signal_t **signal, const char *name)
 Constructor function, creates a new signal. More...
 
int amxp_signal_delete (amxp_signal_t **const signal)
 Destructor function, deletes a signal. More...
 
void amxp_signal_trigger (amxp_signal_t *const signal, const amxc_var_t *const data)
 Triggers a signal. More...
 
int amxp_signal_emit (const amxp_signal_t *const signal, const amxc_var_t *const data)
 Emits a signal. More...
 
int amxp_signal_read (void)
 Reads from the amxp signal file descriptor. More...
 
int amxp_signal_disconnect_all (amxp_signal_t *const signal)
 Disconnects all slots from the signal. More...
 
const char * amxp_signal_name (const amxp_signal_t *const signal)
 Gets the name of the signal. More...
 
bool amxp_signal_has_slots (const amxp_signal_t *const signal)
 Checks if the signal has slots conencted. More...
 
int amxp_signal_fd (void)
 Gets the amxp signal file descriptor. More...
 
 CONSTRUCTOR_LVL (101)
 
 DESTRUCTOR_LVL (101)
 

Variables

static signal_ctrl_t amxp_sigctrl
 
static amxp_signal_mngr_t amxp_sigmngr
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxp_signal.c.

Typedef Documentation

◆ signal_ctrl_t

typedef struct _signal_ctrl signal_ctrl_t

◆ signal_queue_item_t

Function Documentation

◆ amxp_deferred_queue()

static int amxp_deferred_queue ( amxp_signal_mngr_t sigmngr,
amxp_deferred_fn_t  fn,
const amxc_var_t *const  data,
void *  priv 
)
static

Definition at line 151 of file amxp_signal.c.

154  {
155  int retval = -1;
156  signal_queue_item_t* item = (signal_queue_item_t*) calloc(1, sizeof(signal_queue_item_t));
157  when_null(item, exit);
158 
159  amxc_var_init(&item->sig_data);
160  if(data != NULL) {
161  when_failed(amxc_var_copy(&item->sig_data, data), exit);
162  }
163  item->fn = fn;
164  item->priv = priv;
165  amxc_lqueue_add(&sigmngr->signal_queue, &item->it);
166 
167  if(!sigmngr->suspended) {
168  amxc_llist_append(&amxp_sigctrl.pending_sigmngrs, &sigmngr->it);
169  }
170 
171  retval = 0;
172 
173 exit:
174  if((retval != 0) && (item != NULL)) {
175  amxc_var_clean(&item->sig_data);
176  free(item);
177  }
178  return retval;
179 }
static signal_ctrl_t amxp_sigctrl
Definition: amxp_signal.c:88
amxc_llist_it_t it
Definition: amxp_signal.h:107
amxc_lqueue_t signal_queue
Definition: amxp_signal.h:105
amxc_llist_t pending_sigmngrs
Definition: amxp_signal.c:75
amxc_lqueue_it_t it
Definition: amxp_signal.c:82
amxc_var_t sig_data
Definition: amxp_signal.c:81
amxp_deferred_fn_t fn
Definition: amxp_signal.c:84
static amxp_signal_mngr_t * sigmngr

◆ amxp_free_queued_signals()

static void amxp_free_queued_signals ( amxc_lqueue_it_t *  it)
static

Definition at line 114 of file amxp_signal.c.

114  {
115  signal_queue_item_t* item = amxc_llist_it_get_data(it, signal_queue_item_t, it);
116  amxc_var_clean(&item->sig_data);
117  free(item->sig_name);
118  free(item);
119 }

◆ amxp_free_signals()

static void amxp_free_signals ( UNUSED const char *  key,
amxc_htable_it_t *  it 
)
static

Definition at line 107 of file amxp_signal.c.

108  {
109  amxp_signal_t* signal = amxc_htable_it_get_data(it, amxp_signal_t, hit);
111  free(signal);
112 }
int amxp_signal_disconnect_all(amxp_signal_t *const signal)
Disconnects all slots from the signal.
Definition: amxp_signal.c:806
Structure containing the signal information.
Definition: amxp_signal.h:119

◆ amxp_free_slots()

void amxp_free_slots ( amxc_llist_it_t *  it)

Definition at line 99 of file amxp_signal.c.

99  {
100  amxp_slot_t* slot = amxc_llist_it_get_data(it, amxp_slot_t, it);
101  amxc_llist_it_take(it);
102  amxp_expr_delete(&slot->expr);
103  free(slot->regexp);
104  free(slot);
105 }
void amxp_expr_delete(amxp_expr_t **expr)
Deletes a previously allocated expression structure.
amxp_expr_t * expr

◆ amxp_get_sigmngr()

amxp_signal_mngr_t* amxp_get_sigmngr ( amxp_signal_mngr_t sig_mngr)

Definition at line 315 of file amxp_signal.c.

315  {
316  return (sig_mngr == NULL) ? &amxp_sigmngr : sig_mngr;
317 }
static amxp_signal_mngr_t amxp_sigmngr
Definition: amxp_signal.c:89

◆ amxp_get_sigmngrs()

void amxp_get_sigmngrs ( amxc_llist_t **  sigmngrs,
amxc_llist_t **  pending_sigmngrs 
)

Definition at line 319 of file amxp_signal.c.

320  {
321  *sigmngrs = &amxp_sigctrl.sigmngrs;
322  *pending_sigmngrs = &amxp_sigctrl.pending_sigmngrs;
323 }
amxc_llist_t sigmngrs
Definition: amxp_signal.c:74

◆ amxp_get_signals()

const amxc_htable_t* amxp_get_signals ( const amxp_signal_mngr_t sig_mngr)

Definition at line 325 of file amxp_signal.c.

325  {
326  sig_mngr = (sig_mngr == NULL) ? &amxp_sigmngr : sig_mngr;
327  return &sig_mngr->signals;
328 }
amxc_htable_t signals
Definition: amxp_signal.h:104

◆ amxp_sigmngr_garbage_collect()

static void amxp_sigmngr_garbage_collect ( amxp_signal_mngr_t sig_mngr)
static

Definition at line 292 of file amxp_signal.c.

292  {
293  when_null(sig_mngr, exit);
294 
295  if(sig_mngr->deleted && (sig_mngr != &amxp_sigmngr)) {
296  amxp_sigmngr_delete(&sig_mngr);
297  } else {
298  sig_mngr->deleted = false;
299  amxc_htable_for_each(hit, &sig_mngr->signals) {
300  amxp_signal_t* sig = amxc_container_of(hit, amxp_signal_t, hit);
302  }
303  amxc_llist_for_each(it, &sig_mngr->regexp_slots) {
304  amxp_slot_t* slot = amxc_llist_it_get_data(it, amxp_slot_t, it);
305  if(slot->deleted) {
306  amxc_llist_it_clean(it, amxp_free_slots);
307  }
308  }
309  }
310 
311 exit:
312  return;
313 }
static void amxp_signal_garbage_collect(amxp_signal_t *signal)
Definition: amxp_signal.c:274
void amxp_free_slots(amxc_llist_it_t *it)
Definition: amxp_signal.c:99
int amxp_sigmngr_delete(amxp_signal_mngr_t **sig_mngr)
Destructor function, deletes a signal manager instance.
Definition: amxp_signal.c:349
amxc_llist_t regexp_slots
Definition: amxp_signal.h:106

◆ amxp_sigmngr_trigger_regexp()

static void amxp_sigmngr_trigger_regexp ( amxp_signal_mngr_t sig_mngr,
const char *  name,
const amxc_var_t *const  data 
)
static

Definition at line 243 of file amxp_signal.c.

245  {
246  amxp_signal_t* signal = amxp_sigmngr_find_signal(sig_mngr, name);
247  if(signal != NULL) {
248  signal->triggered = true;
249  }
250 
251  sig_mngr->triggered = true;
252  amxc_llist_for_each(it, (&sig_mngr->regexp_slots)) {
253  regex_t regexp;
254  amxp_slot_t* slot = amxc_llist_it_get_data(it, amxp_slot_t, it);
255  if(slot->deleted) {
256  continue;
257  }
258  regcomp(&regexp, slot->regexp, REG_NOSUB | REG_EXTENDED);
259  if(regexec(&regexp, name, 0, NULL, 0) == 0) {
260  amxp_slot_trigger(slot, name, data);
261  }
262  regfree(&regexp);
263  if(sig_mngr->deleted || !sig_mngr->enabled) {
264  break;
265  }
266  }
267 
268  if(signal != NULL) {
269  signal->triggered = false;
270  }
271  sig_mngr->triggered = false;
272 }
static void amxp_slot_trigger(const amxp_slot_t *const slot, const char *name, const amxc_var_t *const data)
Definition: amxp_signal.c:230
amxp_signal_t * amxp_sigmngr_find_signal(const amxp_signal_mngr_t *const sig_mngr, const char *name)
Get the pointer to the signal.
Definition: amxp_signal.c:475

◆ amxp_signal_create_pipe()

static int amxp_signal_create_pipe ( void  )
static

Definition at line 205 of file amxp_signal.c.

205  {
206  int flags = 0;
207  int retval = pipe(amxp_sigctrl.sigpipe);
208  when_true(retval != 0, exit);
209 
210  flags = fcntl(amxp_sigctrl.sigpipe[0], F_GETFL, 0);
211  when_true(flags < 0, exit);
212  when_true(fcntl(amxp_sigctrl.sigpipe[0], F_SETFL, flags | O_NONBLOCK) < 0, exit);
213  when_true(fcntl(amxp_sigctrl.sigpipe[0], F_SETFD, amxp_sigctrl.sigpipe[0] | FD_CLOEXEC) < 0, exit);
214  when_true(fcntl(amxp_sigctrl.sigpipe[1], F_SETFD, amxp_sigctrl.sigpipe[1] | FD_CLOEXEC) < 0, exit);
215 
216  retval = 0;
217 
218 exit:
219  if(retval != 0) {
220  if(amxp_sigctrl.sigpipe[0] != -1) {
221  close(amxp_sigctrl.sigpipe[0]);
222  close(amxp_sigctrl.sigpipe[1]);
223  }
224  amxp_sigctrl.sigpipe[0] = -1;
225  amxp_sigctrl.sigpipe[1] = -1;
226  }
227  return retval;
228 }
int sigpipe[2]
Definition: amxp_signal.c:72

◆ amxp_signal_dequeue()

static signal_queue_item_t* amxp_signal_dequeue ( void  )
static

Definition at line 181 of file amxp_signal.c.

181  {
182  signal_queue_item_t* item = NULL;
183  amxp_signal_mngr_t* sig_mngr = NULL;
184  amxc_lqueue_it_t* sig_it = NULL;
185 
186  amxc_llist_it_t* it = amxc_llist_get_first(&amxp_sigctrl.pending_sigmngrs);
187  when_null(it, exit);
188 
189  sig_mngr = amxc_llist_it_get_data(it, amxp_signal_mngr_t, it);
190  amxc_llist_append(&amxp_sigctrl.pending_sigmngrs, &sig_mngr->it);
191 
192  sig_it = amxc_lqueue_remove(&sig_mngr->signal_queue);
193  item = amxc_llist_it_get_data(sig_it, signal_queue_item_t, it);
194 
195  item->sig_mngr = sig_mngr;
196 
197  if(amxc_lqueue_is_empty(&sig_mngr->signal_queue)) {
198  amxc_llist_append(&amxp_sigctrl.sigmngrs, it);
199  }
200 
201 exit:
202  return item;
203 }
Structure containing the signal manager information.
Definition: amxp_signal.h:103
amxp_signal_mngr_t * sig_mngr
Definition: amxp_signal.c:83

◆ amxp_signal_garbage_collect()

static void amxp_signal_garbage_collect ( amxp_signal_t signal)
static

Definition at line 274 of file amxp_signal.c.

274  {
275  when_null(signal, exit);
276 
277  if(signal->mngr == NULL) {
278  amxc_htable_it_clean(&signal->hit, amxp_free_signals);
279  } else {
280  amxc_llist_for_each(it, (&signal->slots)) {
281  amxp_slot_t* slot = amxc_llist_it_get_data(it, amxp_slot_t, it);
282  if(slot->deleted) {
283  amxc_llist_it_clean(it, amxp_free_slots);
284  }
285  }
286  }
287 
288 exit:
289  return;
290 }
static void amxp_free_signals(UNUSED const char *key, amxc_htable_it_t *it)
Definition: amxp_signal.c:107
amxc_llist_t slots
Definition: amxp_signal.h:121
amxp_signal_mngr_t * mngr
Definition: amxp_signal.h:123
amxc_htable_it_t hit
Definition: amxp_signal.h:120

◆ amxp_signal_queue()

static int amxp_signal_queue ( const amxp_signal_t *const  signal,
const amxc_var_t *const  data 
)
static

Definition at line 121 of file amxp_signal.c.

122  {
123  int retval = -1;
124  signal_queue_item_t* item = (signal_queue_item_t*) calloc(1, sizeof(signal_queue_item_t));
125  when_null(item, exit);
126  item->sig_name = (char*) calloc(1, strlen(signal->name) + 1);
127  when_null(item->sig_name, exit);
128 
129  amxc_var_init(&item->sig_data);
130  if(data != NULL) {
131  when_failed(amxc_var_copy(&item->sig_data, data), exit);
132  }
133  strcpy(item->sig_name, signal->name);
134  amxc_lqueue_add(&signal->mngr->signal_queue, &item->it);
135 
136  if(!signal->mngr->suspended) {
137  amxc_llist_append(&amxp_sigctrl.pending_sigmngrs, &signal->mngr->it);
138  }
139 
140  retval = 0;
141 
142 exit:
143  if((retval != 0) && (item != NULL)) {
144  free(item->sig_name);
145  amxc_var_clean(&item->sig_data);
146  free(item);
147  }
148  return retval;
149 }
const char * name
Definition: amxp_signal.h:122

◆ amxp_signal_queue_lock()

static int amxp_signal_queue_lock ( void  )
static

Definition at line 91 of file amxp_signal.c.

91  {
92  return pthread_mutex_lock(&amxp_sigctrl.mutex);
93 }
pthread_mutex_t mutex
Definition: amxp_signal.c:76

◆ amxp_signal_queue_unlock()

static int amxp_signal_queue_unlock ( void  )
static

Definition at line 95 of file amxp_signal.c.

95  {
96  return pthread_mutex_unlock(&amxp_sigctrl.mutex);
97 }

◆ amxp_slot_trigger()

static void amxp_slot_trigger ( const amxp_slot_t *const  slot,
const char *  name,
const amxc_var_t *const  data 
)
static

Definition at line 230 of file amxp_signal.c.

232  {
233  if(slot->expr != NULL) {
235  if((data == NULL) || amxp_expr_eval_var(slot->expr, data, &status)) {
236  slot->fn(name, data, slot->priv);
237  }
238  } else {
239  slot->fn(name, data, slot->priv);
240  }
241 }
bool amxp_expr_eval_var(amxp_expr_t *expr, const amxc_var_t *const data, amxp_expr_status_t *status)
Evaluates an expression against a composite variant.
enum _expr_status amxp_expr_status_t
Expression status/error codes.
@ amxp_expr_status_ok
amxp_slot_fn_t fn

◆ CONSTRUCTOR_LVL()

CONSTRUCTOR_LVL ( 101  )

Definition at line 845 of file amxp_signal.c.

845  {
847  amxc_llist_init(&amxp_sigctrl.sigmngrs);
848  amxc_lqueue_init(&amxp_sigctrl.pending_sigmngrs);
851  pthread_mutex_init(&amxp_sigctrl.mutex, NULL);
852 
853  amxp_sigmngr_add_signal(NULL, "connection-added");
854  amxp_sigmngr_add_signal(NULL, "connection-wait-write");
855  amxp_sigmngr_add_signal(NULL, "listen-added");
856  amxp_sigmngr_add_signal(NULL, "listen-deleted");
857  amxp_sigmngr_add_signal(NULL, "connection-deleted");
858 }
static int amxp_signal_create_pipe(void)
Definition: amxp_signal.c:205
int amxp_sigmngr_add_signal(amxp_signal_mngr_t *const sig_mngr, const char *name)
Adds a signal to a signal manager.
Definition: amxp_signal.c:433
int amxp_sigmngr_init(amxp_signal_mngr_t *sig_mngr)
Initializing function, initializes members of the amxp_signal_mngr_t structure.
Definition: amxp_signal.c:377
int amxp_signal_new(amxp_signal_mngr_t *sig_mngr, amxp_signal_t **signal, const char *name)
Constructor function, creates a new signal.
Definition: amxp_signal.c:620
amxp_signal_t * sigall
Definition: amxp_signal.c:73

◆ DESTRUCTOR_LVL()

DESTRUCTOR_LVL ( 101  )

Definition at line 860 of file amxp_signal.c.

860  {
862  if(amxp_sigctrl.sigpipe[0] != -1) {
863  close(amxp_sigctrl.sigpipe[0]);
864  }
865  if(amxp_sigctrl.sigpipe[1] != -1) {
866  close(amxp_sigctrl.sigpipe[1]);
867  }
868  pthread_mutex_destroy(&amxp_sigctrl.mutex);
869 }
int amxp_sigmngr_clean(amxp_signal_mngr_t *sig_mngr)
Clean-up functions, cleans-up all members of a amxp_signal_mngr_t structure.
Definition: amxp_signal.c:405

Variable Documentation

◆ amxp_sigctrl

signal_ctrl_t amxp_sigctrl
static

Definition at line 88 of file amxp_signal.c.

◆ amxp_sigmngr

amxp_signal_mngr_t amxp_sigmngr
static

Definition at line 89 of file amxp_signal.c.