QuickIO  0.2
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
qev.h
Go to the documentation of this file.
1 
27 #pragma once
28 
32 #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_32
33 
37 #define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_32
38 
42 #define _GNU_SOURCE
43 
44 #include <arpa/inet.h>
45 #include <errno.h>
46 #include <glib.h>
47 #include <glib/gstdio.h>
48 #include <netdb.h>
49 #include <netinet/in.h>
50 #include <netinet/tcp.h>
51 #include <openssl/ssl.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <sys/resource.h>
55 #include <sys/socket.h>
56 #include <sys/times.h>
57 #include <sys/types.h>
58 #include <unistd.h>
59 
63 #define QEV_VERSION_MAJOR 0
64 
68 #define QEV_VERSION_MINOR 2
69 
73 #define QEV_VERSION_MICRO 0
74 
75 #ifndef VERSION_NAME
76 
79  #define VERSION_NAME UNKNOWN
80 #endif
81 
82 #ifndef VERSION_MAJOR
83 
86  #define VERSION_MAJOR 0
87 #endif
88 
89 #ifndef VERSION_MINOR
90 
93  #define VERSION_MINOR 0
94 #endif
95 
96 #ifndef VERSION_MICRO
97 
100  #define VERSION_MICRO 0
101 #endif
102 
103 #if !defined(__linux__)
104  #error quick-event is not able to run on this platform.
105 #endif
106 
107 #ifndef QEV_SSL_CIPHERS
108 
111  #define QEV_SSL_CIPHERS "HIGH:!aNULL:!MD5:"
112 #endif
113 
114 #ifndef QEV_CLIENT
115 
118  #define QEV_CLIENT qev_client
119 #endif
120 
124 struct QEV_CLIENT;
125 
132 #define QEV_MS_TO_USEC(ms) (ms * 1000)
133 
140 #define QEV_MS_TO_NSEC(ms) (QEV_MS_TO_USEC(ms) * 1000)
141 
148 #define QEV_SEC_TO_USEC(secs) QEV_MS_TO_USEC(secs * 1000)
149 
153 #define QEV_YIELD_AFTER 1024
154 
159 #define QEV_WAIT_FOR(cond) { \
160  register guint spins = 0; \
161  while (!(cond)) { \
162  if (++spins > QEV_YIELD_AFTER) { \
163  g_thread_yield(); \
164  } \
165  }}
166 
170 typedef int qev_fd_t;
171 
175 typedef struct qev_timeout qev_timeout_t;
176 
180 typedef void (*qev_cb)();
181 
185 typedef void (*qev_free_fn)(void*);
186 
191 
195 struct qev_flags {
200  gboolean listening:1;
201 
205  gboolean udp:1;
206 
210  gboolean timer:1;
211 
215  gboolean ssl:1;
216 
220  gboolean ssl_handshaking:1;
221 
225  gboolean opened:1;
226 
231  gboolean closing:1;
232 
236  gboolean closed:1;
237 
243  gboolean surrogate:1;
244 };
245 
254 struct qev_client {
265  GString *rbuff;
266 
271  GString *_wbuff;
272 
277  union {
285  SSL *ssl;
286 
290  SSL_CTX *ssl_ctx;
291 
296  } _type;
297 
304 
309 
313  guint _lock;
314 
319  qev_fd_t _fd;
320 
325  gint32 _clients_slot;
326 
331  guint _refs;
332 
338  gint _read_operations;
339 
344 
349  gchar ip[INET6_ADDRSTRLEN];
350 };
351 
355 typedef void (*qev_client_cb)(struct QEV_CLIENT *client, void *data);
356 
365 
370 
375 
380 
386 
391 
396 };
397 
402 gint64 qev_time;
403 
409 
423 void qev_init(const gchar *app_name, gchar **argv, gint argc);
424 
428 void qev_run();
429 
436 void qev_kill();
437 
445 void qev_wait_for_exit();
446 
453 void qev_exit();
454 
464 void qev_listen(const gchar *ip_address, const guint16 port);
465 
486 void qev_listen_ssl(
487  const gchar *ip_address,
488  const guint16 port,
489  const gchar *cert_path0,
490  const gchar *key_path0,
491  const gchar *cert_path1,
492  const gchar *key_path1);
493 
502 void qev_listen_unix(const gchar *path);
503 
512 void qev_listen_udp(const gchar *ip_address, const guint16 port);
513 
517 void qev_chuser(const char *username);
518 
523 void qev_setnofile(const gint nofile);
524 
548 void qev_timer(
549  const qev_cb fn,
550  const guint seconds,
551  const guint ms);
552 
558 const gchar* qev_get_hostname();
559 
575 struct QEV_CLIENT* qev_surrogate_new();
576 
586 GString* qev_surrogate_flush(struct QEV_CLIENT *surrogate);
587 
603 void qev_write(struct QEV_CLIENT *client, const gchar *buff, const gsize len);
604 
615 void qev_writef(struct QEV_CLIENT *client, const gchar *format, ...)
616  G_GNUC_PRINTF(2, 3);
617 
628 void qev_close(struct QEV_CLIENT *client, guint reason);
629 
639 gboolean qev_is_surrogate(struct QEV_CLIENT *client);
640 
650 gboolean qev_is_closing(struct QEV_CLIENT *client);
651 
677 void qev_foreach(qev_client_cb cb, gint threads, void *data);
678 
682 struct QEV_CLIENT* qev_ref(struct QEV_CLIENT *client);
683 
687 void qev_unref(struct QEV_CLIENT *client);
688 
693 void qev_unref0(struct QEV_CLIENT **client);
694 
698 void qev_unref_as_free(void *client_);
699 
712 void qev_lock(struct QEV_CLIENT *client);
713 
720 void qev_unlock(struct QEV_CLIENT *client);
721 
741 void qev_timeout(struct QEV_CLIENT *client, qev_timeout_t **timeout);
742 
749 void qev_timeout_clear(qev_timeout_t **timeout);
750 
758 void qev_chuser(const gchar *username);
759 
765 void qev_on_before_run();
766 
773 void qev_on_open(struct QEV_CLIENT *client);
774 
785 void qev_on_close(struct QEV_CLIENT *client, guint reason);
786 
800 void qev_on_read(struct QEV_CLIENT *client);
801 
812 void qev_on_udp(const gchar *msg, const gsize len, const gchar *ip);
813 
819 void qev_on_tick();
820 
827 void qev_on_exit();
828 
834 struct QEV_CLIENT* qev_client_new();
835 
840 void qev_client_free(struct QEV_CLIENT *client);
841 
842 #include "bench.h"
843 #include "buffer.h"
844 #include "cleanup.h"
845 #include "config.h"
846 #include "fair.h"
847 #include "http.h"
848 #include "job.h"
849 #include "json.h"
850 #include "latch.h"
851 #include "list.h"
852 #include "lock.h"
853 #include "log.h"
854 #include "mock.h"
855 #include "pool.h"
856 #include "queue.h"
857 #include "rsock.h"
858 #include "safe.h"
859 #include "stats.h"
860 #include "strfuncs.h"
GString * qev_surrogate_flush(struct QEV_CLIENT *surrogate)
Steal the entire write buffer from the surrogate client.
gboolean closed
Indicates that a client is in the process of being closed.
Definition: qev.h:236
void qev_chuser(const char *username)
Run as this user.
Optimizations to GLib's string functions.
Provides a read-write spin lock.
struct QEV_CLIENT * qev_surrogate_new()
Create a surrogate client.
A system call failed somewhere and the client must die.
Definition: qev.h:379
Provides a latch that you can wait on.
SSL_CTX * ssl_ctx
For server sockets.
Definition: qev.h:290
Provides a thread-local / globally shared pool of objects.
void qev_listen(const gchar *ip_address, const guint16 port)
Instruct quick event to listen on a socket for connections and route them into the event handler...
void qev_unref0(struct QEV_CLIENT **client)
Release a reference to the client and set the corresponding memory location to NULL.
Allows for mocking any function call (typically used for syscalls) to see how they operate in failure...
void qev_on_close(struct QEV_CLIENT *client, guint reason)
Notification that a client has closed / been closed.
struct QEV_CLIENT * qev_ref(struct QEV_CLIENT *client)
Take a reference to the client.
void qev_kill()
Unblocks all threads waiting for QEV to exit.
gint64 qev_monotonic
An approximate monotonic time, set from g_get_monotonic_time(), updated at least every 100ms...
Definition: qev.h:408
void qev_on_udp(const gchar *msg, const gsize len, const gchar *ip)
A notification that there is a new UDP message waiting.
void qev_unref(struct QEV_CLIENT *client)
Release a reference to the client.
struct qev_flags _flags
This client's flags.
Definition: qev.h:343
Provides safe math operations that won't overflow.
void qev_run()
Spawns all worker threads and starts QEV running.
Helps with determining if resources can be fairly allocated given current conditions.
gboolean udp
A UDP-bound socket.
Definition: qev.h:205
void qev_wait_for_exit()
Allows you to wait for QEV to exit; really, this is a way to block the main thread while QEV is runni...
qev_timeout_t * _ssl_handshake_timeout
For SSL: timeout clients that don't complete their handshakes.
Definition: qev.h:303
Provides stats aggregation and multiple sinks for collected stats.
SSL * ssl
For clients.
Definition: qev.h:285
const gchar * qev_get_hostname()
Get the name of this host.
Handles configuration for the entire server and exposes a remote-management/monitoring interface...
For data that lives the life of the server, this provides a quick way to create and forget about free...
void qev_lock(struct QEV_CLIENT *client)
Acquire a lock on a client.
gboolean surrogate
Indicates that the client doesn't have a socket sitting behind.
Definition: qev.h:243
Useful utilities for doing asynchronous HTTP requests and parsing HTTP responses. ...
Provides a multiple-producer, multiple-consumer queue.
void qev_on_open(struct QEV_CLIENT *client)
Notification that a new client was accepted.
qJSON is a minimal, in-place, zero-allocation JSON packer and unpacker.
void qev_listen_ssl(const gchar *ip_address, const guint16 port, const gchar *cert_path0, const gchar *key_path0, const gchar *cert_path1, const gchar *key_path1)
Instruct quick event to listen on an SSL socket for connections and route them into the event handler...
struct QEV_CLIENT * qev_client_new()
Create a new client using whatever memory allocator you wish and sized appropriately for your needs...
void qev_unlock(struct QEV_CLIENT *client)
Release a lock on a client.
Provides a buffered socket that reconnects on errors.
void qev_init(const gchar *app_name, gchar **argv, gint argc)
Prepares QEV to run.
Everything that a client needs to function.
Definition: client.h:100
void qev_setnofile(const gint nofile)
Set the limits for the number of open files for this process.
void(* qev_cb)()
A single callback that takes nothing and returns nothing.
Definition: qev.h:180
gboolean closing
Indicates that a client is being closed.
Definition: qev.h:231
gchar ip[INET6_ADDRSTRLEN]
The client's IP.
Definition: qev.h:349
GString * rbuff
Data waiting to be processed.
Definition: qev.h:265
Provides a highly-concurrent, optionally resizable, optimized-for-inserts list.
void qev_writef(struct QEV_CLIENT *client, const gchar *format,...) G_GNUC_PRINTF(2
Allows you to use qev_write in a printf() style.
void qev_timer(const qev_cb fn, const guint seconds, const guint ms)
Add a callback to be fired on a timer.
qev_free_fn qev_data_cb
Function type for something that recieves an argument.
Definition: qev.h:190
gboolean opened
qev_on_open() event has been fired to app
Definition: qev.h:225
Memory pressure has been hit, and the client is being closed as a result.
Definition: qev.h:385
qev_cb timer_fn
For timers.
Definition: qev.h:295
void qev_foreach(qev_client_cb cb, gint threads, void *data)
Runs the callback on all clients.
void qev_exit()
Kill and wait for QEV to exit in one fell swoop.
void qev_client_free(struct QEV_CLIENT *client)
Free the client allocated with qev_client_new().
void qev_listen_udp(const gchar *ip_address, const guint16 port)
Instruct quick event to listen on on a UDP socket for messages.
Provides a simple interface for running jobs in multiple threads at once.
qev_close_reasons
The reasons a client might be closed.
Definition: qev.h:360
guint _lock
For acquiring a lock on a client.
Definition: qev.h:313
void(* qev_client_cb)(struct QEV_CLIENT *client, void *data)
A callback that takes a single client.
Definition: qev.h:355
void qev_on_read(struct QEV_CLIENT *client)
A notification that the client has data for reading.
The client's socket hung up or timed out.
Definition: qev.h:364
The client timed out.
Definition: qev.h:374
gboolean ssl_handshaking
The SSL client is still shaking hands.
Definition: qev.h:220
void qev_on_tick()
Fired after every iteration of the event loop from every QEV thread.
void qev_listen_unix(const gchar *path)
Instruct quick event to create a Unix socket at the given path and listen on it.
Provides a pool of buffers you can use whenever you need a quick buffer.
int qev_fd_t
Sockets are just ints.
Definition: qev.h:170
A read failed.
Definition: qev.h:369
void qev_unref_as_free(void *client_)
So that you can use it as a free function without a cast.
void qev_write(struct QEV_CLIENT *client, const gchar *buff, const gsize len)
Writes data to the client.
void void qev_close(struct QEV_CLIENT *client, guint reason)
Close and free the client when it is safe to do so.
#define QEV_CLIENT
If no client was configured externally, default to qev_client.
Definition: qev.h:118
void qev_timeout_clear(qev_timeout_t **timeout)
Clear a timeout on a client and release your reference to the timeout.
gboolean qev_is_surrogate(struct QEV_CLIENT *client)
Determine if a client is a surrogate.
void * _locking_thread
For the re-entrant part of the lock: holds which thread has the lock.
Definition: qev.h:308
void(* qev_free_fn)(void *)
Function type for a typical free function.
Definition: qev.h:185
gboolean qev_is_closing(struct QEV_CLIENT *client)
Check if a client is closing.
gboolean listening
"listening" client type, meaning that this client accepts connections on its socket ...
Definition: qev.h:200
struct qev_timeout qev_timeout_t
You're never allowed to mess with timeout internals.
Definition: qev.h:175
Provides some useful logging shortcuts.
gint64 qev_time
An approximation of the current time, set from g_get_real_time(), updated at least every 100ms...
Definition: qev.h:402
void qev_on_before_run()
Before the server is about to run (right before when the QEV threads are set into the event loop)...
The server is exiting and on its way to shutdown.
Definition: qev.h:390
void qev_on_exit()
A notification that QEV is going to shut down.
Any flags associated with a client.
Definition: qev.h:195
gboolean timer
Not really a client, but a timer.
Definition: qev.h:210
The number of items in this enum.
Definition: qev.h:395
gboolean ssl
An SSL client.
Definition: qev.h:215
Contains all of the information needed for quick-event to have a functioning client.
Definition: qev.h:254
void qev_timeout(struct QEV_CLIENT *client, qev_timeout_t **timeout)
Set a timeout on a client.