summaryrefslogtreecommitdiff
path: root/src/common/evqueue.h
blob: ffb3860bb78cfab788184f0a259c9e3a98a010c0 (plain)
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*!
 * \file evqueue.h
 *
 * \author Marek Vavrusa <marek.vavrusa@nic.cz>
 *
 * \brief Event queue.
 *
 * \addtogroup common_lib
 * @{
 */

#ifndef _KNOTD_COMMON_EVQUEUE_H_
#define _KNOTD_COMMON_EVQUEUE_H_

#include <pthread.h>
#include <signal.h> // sigset_t
#include <time.h>
#include <sys/time.h>

//#include "knot/common.h"
#include "common/lists.h"

struct event_t;

/*!
 * \brief Event callback.
 *
 * Pointer to whole event structure is passed to the callback.
 * Callback should return 0 on success and negative integer on error.
 *
 * Example callback:
 * \code
 * int print_callback(event_t *t) {
 *    return printf("Callback: %s\n", t->data);
 * }
 * \endcode
 */
typedef int (*event_cb_t)(struct event_t *);

/*!
 * \brief Event structure.
 */
typedef struct event_t {
	node n;            /*!< Node for event queue. */
	int type;          /*!< Event type. */
	struct timeval tv; /*!< Event scheduled time. */
	void *data;        /*!< Usable data ptr. */
	event_cb_t cb;     /*!< Event callback. */
	void *parent;      /*!< Pointer to parent (evqueue, scheduler...) */
} event_t;

/*!
 * \brief Event queue constants.
 */
enum {
	EVQUEUE_READFD  = 0,
	EVQUEUE_WRITEFD = 1
};

/*!
 * \brief Event queue structure.
 */
typedef struct {
	int fds[2]; /*!< Read and Write fds. */
} evqueue_t;

/*!
 * \brief Create new event queue.
 *
 * Event queue is thread-safe and POSIX signal-safe.
 * It uses piped fds for queueing and pselect(2) to
 * wait for events.
 *
 * \retval New instance on success.
 * \retval NULL on error.
 */
evqueue_t *evqueue_new();

/*!
 * \brief Deinitialize and free event queue.
 *
 * \param q Pointer to queue instance.
 * \note *q is set to 0.
 */
void evqueue_free(evqueue_t **q);

/*!
 * \brief Poll for new events.
 *
 * Unblocked signals during polling are specified
 * in a sigmask.
 *
 * \param q Event queue.
 * \param ts Timeout (or NULL for infinite).
 * \param sigmask Bitmask of signals to receive (or NULL).
 *
 * \retval Number of polled events on success.
 * \retval -1 On error or signal interrupt.
 */
int evqueue_poll(evqueue_t *q, const struct timespec *ts, const sigset_t *sigmask);

/*!
 * \brief Return evqueue pollable fd.
 *
 * \param q Event queue.
 *
 * \retval File descriptor available for polling.
 * \retval -1 On error.
 */
static inline int evqueue_pollfd(evqueue_t *q) {
	return q->fds[EVQUEUE_READFD];
}

/*!
 * \brief Read data from event queue.
 *
 * This function is useful for sending custom
 * events or other data types through the event queue.
 *
 * \param q Event queue.
 * \param dst Destination buffer.
 * \param len Number of bytes to read.
 *
 * \retval Number of read bytes on success.
 * \retval -1 on error, \see read(2).
 */
int evqueue_read(evqueue_t *q, void *dst, size_t len);

/*!
 * \brief Write data to event queue.
 *
 * This function is useful for sending custom
 * events or other data types through the event queue.
 *
 * \param q Event queue.
 * \param src Source buffer.
 * \param len Number of bytes to write.
 *
 * \retval Number of written bytes on success.
 * \retval -1 on error, \see write(2).
 */
int evqueue_write(evqueue_t *q, const void *src, size_t len);

/*!
 * \brief Read event from event queue.
 *
 * \param q Event queue.
 * \param ev Event structure for writing.
 *
 * \retval 0 on success.
 * \retval -1 on error.
 */
int evqueue_get(evqueue_t *q, event_t *ev);

/*!
 * \brief Add event to queue.
 *
 * \param q Event queue.
 * \param ev Event structure to read.
 *
 * \retval 0 on success.
 * \retval -1 on error.
 */
int evqueue_add(evqueue_t *q, const event_t *ev);

/* Singleton event queue pointer. */
extern evqueue_t *s_evqueue;

/*!
 * \brief Event queue singleton.
 */
static inline evqueue_t *evqueue() {
	return s_evqueue;
}

/*!
 * \brief Set event queue singleton.
 */
static inline void evqueue_set(evqueue_t *q) {
	s_evqueue = q;
}

#endif /* _KNOTD_COMMON_EVQUEUE_H_ */

/*! @} */