1 | |
---|
2 | #ifndef _E_MSGPORT_H |
---|
3 | #define _E_MSGPORT_H |
---|
4 | |
---|
5 | /* double-linked list yeah another one, deal */ |
---|
6 | typedef struct _EDListNode { |
---|
7 | struct _EDListNode *next; |
---|
8 | struct _EDListNode *prev; |
---|
9 | } EDListNode; |
---|
10 | |
---|
11 | typedef struct _EDList { |
---|
12 | struct _EDListNode *head; |
---|
13 | struct _EDListNode *tail; |
---|
14 | struct _EDListNode *tailpred; |
---|
15 | } EDList; |
---|
16 | |
---|
17 | #define E_DLIST_INITIALISER(l) { (EDListNode *)&l.tail, 0, (EDListNode *)&l.head } |
---|
18 | |
---|
19 | void e_dlist_init(EDList *v); |
---|
20 | EDListNode *e_dlist_addhead(EDList *l, EDListNode *n); |
---|
21 | EDListNode *e_dlist_addtail(EDList *l, EDListNode *n); |
---|
22 | EDListNode *e_dlist_remove(EDListNode *n); |
---|
23 | EDListNode *e_dlist_remhead(EDList *l); |
---|
24 | EDListNode *e_dlist_remtail(EDList *l); |
---|
25 | int e_dlist_empty(EDList *l); |
---|
26 | int e_dlist_length(EDList *l); |
---|
27 | |
---|
28 | /* message ports - a simple inter-thread 'ipc' primitive */ |
---|
29 | /* opaque handle */ |
---|
30 | typedef struct _EMsgPort EMsgPort; |
---|
31 | |
---|
32 | /* header for any message */ |
---|
33 | typedef struct _EMsg { |
---|
34 | EDListNode ln; |
---|
35 | EMsgPort *reply_port; |
---|
36 | } EMsg; |
---|
37 | |
---|
38 | EMsgPort *e_msgport_new(void); |
---|
39 | void e_msgport_destroy(EMsgPort *mp); |
---|
40 | /* get a fd that can be used to wait on the port asynchronously */ |
---|
41 | int e_msgport_fd(EMsgPort *mp); |
---|
42 | void e_msgport_put(EMsgPort *mp, EMsg *msg); |
---|
43 | EMsg *e_msgport_wait(EMsgPort *mp); |
---|
44 | EMsg *e_msgport_get(EMsgPort *mp); |
---|
45 | void e_msgport_reply(EMsg *msg); |
---|
46 | #ifdef HAVE_NSS |
---|
47 | struct PRFileDesc *e_msgport_prfd(EMsgPort *mp); |
---|
48 | #endif |
---|
49 | |
---|
50 | /* e threads, a server thread with a message based request-response, and flexible queuing */ |
---|
51 | typedef struct _EThread EThread; |
---|
52 | |
---|
53 | typedef enum { |
---|
54 | E_THREAD_QUEUE = 0, /* run one by one, until done, if the queue_limit is reached, discard new request */ |
---|
55 | E_THREAD_DROP, /* run one by one, until done, if the queue_limit is reached, discard oldest requests */ |
---|
56 | E_THREAD_NEW, /* always run in a new thread, if the queue limit is reached, new requests are |
---|
57 | stored in the queue until a thread becomes available for it, creating a thread pool */ |
---|
58 | } e_thread_t; |
---|
59 | |
---|
60 | typedef void (*EThreadFunc)(EThread *, EMsg *, void *data); |
---|
61 | |
---|
62 | EThread *e_thread_new(e_thread_t type); |
---|
63 | void e_thread_destroy(EThread *e); |
---|
64 | void e_thread_set_queue_limit(EThread *e, int limit); |
---|
65 | void e_thread_set_msg_lost(EThread *e, EThreadFunc destroy, void *data); |
---|
66 | void e_thread_set_msg_destroy(EThread *e, EThreadFunc destroy, void *data); |
---|
67 | void e_thread_set_reply_port(EThread *e, EMsgPort *reply_port); |
---|
68 | void e_thread_set_msg_received(EThread *e, EThreadFunc received, void *data); |
---|
69 | void e_thread_put(EThread *e, EMsg *msg); |
---|
70 | int e_thread_busy(EThread *e); |
---|
71 | |
---|
72 | /* sigh, another mutex interface, this one allows different mutex types, portably */ |
---|
73 | typedef struct _EMutex EMutex; |
---|
74 | |
---|
75 | typedef enum _e_mutex_t { |
---|
76 | E_MUTEX_SIMPLE, /* == pthread_mutex */ |
---|
77 | E_MUTEX_REC, /* recursive mutex */ |
---|
78 | } e_mutex_t; |
---|
79 | |
---|
80 | EMutex *e_mutex_new(e_mutex_t type); |
---|
81 | int e_mutex_destroy(EMutex *m); |
---|
82 | int e_mutex_lock(EMutex *m); |
---|
83 | int e_mutex_unlock(EMutex *m); |
---|
84 | void e_mutex_assert_locked(EMutex *m); |
---|
85 | |
---|
86 | #endif |
---|