aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-msgport.h
blob: 6347564c0fbe7780c9c8580aa3f95ca3d770c6f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

#ifndef _E_MSGPORT_H
#define _E_MSGPORT_H

#include <time.h>
#include <glib.h>

/* double-linked list yeah another one, deal */
typedef struct _EDListNode {
    struct _EDListNode *next;
    struct _EDListNode *prev;
} EDListNode;

typedef struct _EDList {
    struct _EDListNode *head;
    struct _EDListNode *tail;
    struct _EDListNode *tailpred;
} EDList;

#define E_DLIST_INITIALISER(l) { (EDListNode *)&l.tail, 0, (EDListNode *)&l.head }

void e_dlist_init(EDList *v);
EDListNode *e_dlist_addhead(EDList *l, EDListNode *n);
EDListNode *e_dlist_addtail(EDList *l, EDListNode *n);
EDListNode *e_dlist_remove(EDListNode *n);
EDListNode *e_dlist_remhead(EDList *l);
EDListNode *e_dlist_remtail(EDList *l);
int e_dlist_empty(EDList *l);
int e_dlist_length(EDList *l);

/* a time-based cache */
typedef struct _EMCache EMCache;
typedef struct _EMCacheNode EMCacheNode;

/* subclass this for your data nodes, EMCache is opaque */
struct _EMCacheNode {
    struct _EMCacheNode *next, *prev;
    char *key;
    int ref_count;
    time_t stamp;
};

EMCache *em_cache_new(time_t timeout, size_t nodesize, GFreeFunc nodefree);
void em_cache_destroy(EMCache *emc);
EMCacheNode *em_cache_lookup(EMCache *emc, const char *key);
EMCacheNode *em_cache_node_new(EMCache *emc, const char *key);
void em_cache_node_unref(EMCache *emc, EMCacheNode *n);
void em_cache_add(EMCache *emc, EMCacheNode *n);
void em_cache_clear(EMCache *emc);

/* message ports - a simple inter-thread 'ipc' primitive */
/* opaque handle */
typedef struct _EMsgPort EMsgPort;

/* header for any message */
typedef struct _EMsg {
    EDListNode ln;
    EMsgPort *reply_port;
} EMsg;

EMsgPort *e_msgport_new(void);
void e_msgport_destroy(EMsgPort *mp);
/* get a fd that can be used to wait on the port asynchronously */
int e_msgport_fd(EMsgPort *mp);
void e_msgport_put(EMsgPort *mp, EMsg *msg);
EMsg *e_msgport_wait(EMsgPort *mp);
EMsg *e_msgport_get(EMsgPort *mp);
void e_msgport_reply(EMsg *msg);
#ifdef HAVE_NSS
struct PRFileDesc *e_msgport_prfd(EMsgPort *mp);
#endif

/* e threads, a server thread with a message based request-response, and flexible queuing */
typedef struct _EThread EThread;

typedef enum {
    E_THREAD_QUEUE = 0, /* run one by one, until done, if the queue_limit is reached, discard new request */
    E_THREAD_DROP,      /* run one by one, until done, if the queue_limit is reached, discard oldest requests */
    E_THREAD_NEW,       /* always run in a new thread, if the queue limit is reached, new requests are
                   stored in the queue until a thread becomes available for it, creating a thread pool */
} e_thread_t;

typedef void (*EThreadFunc)(EThread *, EMsg *, void *data);

EThread *e_thread_new(e_thread_t type);
void e_thread_destroy(EThread *e);
void e_thread_set_queue_limit(EThread *e, int limit);
void e_thread_set_msg_lost(EThread *e, EThreadFunc destroy, void *data);
void e_thread_set_msg_destroy(EThread *e, EThreadFunc destroy, void *data);
void e_thread_set_reply_port(EThread *e, EMsgPort *reply_port);
void e_thread_set_msg_received(EThread *e, EThreadFunc received, void *data);
void e_thread_put(EThread *e, EMsg *msg);
int e_thread_busy(EThread *e);

/* sigh, another mutex interface, this one allows different mutex types, portably */
typedef struct _EMutex EMutex;

typedef enum _e_mutex_t {
    E_MUTEX_SIMPLE,     /* == pthread_mutex */
    E_MUTEX_REC,        /* recursive mutex */
} e_mutex_t;

EMutex *e_mutex_new(e_mutex_t type);
int e_mutex_destroy(EMutex *m);
int e_mutex_lock(EMutex *m);
int e_mutex_unlock(EMutex *m);
void e_mutex_assert_locked(EMutex *m);
/* this uses pthread cond's */
int e_mutex_cond_wait(void *cond, EMutex *m);

#endif