Provides all the qev_* functions that are needed for creating an event loop. More...
#include <arpa/inet.h>#include <errno.h>#include <glib.h>#include <glib/gstdio.h>#include <netdb.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <openssl/ssl.h>#include <stdio.h>#include <string.h>#include <sys/resource.h>#include <sys/socket.h>#include <sys/times.h>#include <sys/types.h>#include <unistd.h>#include "bench.h"#include "buffer.h"#include "cleanup.h"#include "config.h"#include "fair.h"#include "http.h"#include "job.h"#include "json.h"#include "latch.h"#include "list.h"#include "lock.h"#include "log.h"#include "mock.h"#include "pool.h"#include "queue.h"#include "rsock.h"#include "safe.h"#include "stats.h"#include "strfuncs.h"Go to the source code of this file.
Classes | |
| struct | qev_flags |
| Any flags associated with a client. More... | |
| struct | qev_client |
| Contains all of the information needed for quick-event to have a functioning client. More... | |
Macros | |
| #define | GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_32 |
| Only allow glib 2.32 as that's the highest on Debian Wheezy. | |
| #define | GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_32 |
| Only allow glib 2.32 as that's the highest on Debian Wheezy. | |
| #define | _GNU_SOURCE |
| Give us access to more features. | |
| #define | QEV_VERSION_MAJOR 0 |
| Current major version of quick-event. | |
| #define | QEV_VERSION_MINOR 2 |
| Current minor version of quick-event. | |
| #define | QEV_VERSION_MICRO 0 |
| Current micro version of quick-event. | |
| #define | VERSION_NAME UNKNOWN |
| Name of the application being compiled with the server. | |
| #define | VERSION_MAJOR 0 |
| Major version application being compiled with the server. | |
| #define | VERSION_MINOR 0 |
| Minor version application being compiled with the server. | |
| #define | VERSION_MICRO 0 |
| Micro version application being compiled with the server. | |
| #define | QEV_SSL_CIPHERS "HIGH:!aNULL:!MD5:" |
| Whatever ciphers SSL should use. | |
| #define | QEV_CLIENT qev_client |
| If no client was configured externally, default to qev_client. | |
| #define | QEV_MS_TO_USEC(ms) (ms * 1000) |
| Convert milliseconds to microseconds. More... | |
| #define | QEV_MS_TO_NSEC(ms) (QEV_MS_TO_USEC(ms) * 1000) |
| Convert milliseconds to nanoseconds. More... | |
| #define | QEV_SEC_TO_USEC(secs) QEV_MS_TO_USEC(secs * 1000) |
| Convert seconds to microseconds. More... | |
| #define | QEV_YIELD_AFTER 1024 |
| The number of spins anything should yield after. | |
| #define | QEV_WAIT_FOR(cond) |
| Waits for a condition to be true, yielding in the process if it waits too long. More... | |
Typedefs | |
| typedef int | qev_fd_t |
| Sockets are just ints. | |
| typedef struct qev_timeout | qev_timeout_t |
| You're never allowed to mess with timeout internals. | |
| typedef void(* | qev_cb )() |
| A single callback that takes nothing and returns nothing. | |
| typedef void(* | qev_free_fn )(void *) |
| Function type for a typical free function. | |
| typedef qev_free_fn | qev_data_cb |
| Function type for something that recieves an argument. | |
| typedef void(* | qev_client_cb )(struct QEV_CLIENT *client, void *data) |
| A callback that takes a single client. | |
Enumerations | |
| enum | qev_close_reasons { QEV_CLOSE_HUP, QEV_CLOSE_READ_FAIL, QEV_CLOSE_TIMEOUT, QEV_CLOSE_OS_ERROR, QEV_CLOSE_OUT_OF_MEM, QEV_CLOSE_EXITING, QEV_CLOSE_LEN } |
| The reasons a client might be closed. More... | |
Functions | |
| void | qev_init (const gchar *app_name, gchar **argv, gint argc) |
| Prepares QEV to run. More... | |
| void | qev_run () |
| Spawns all worker threads and starts QEV running. | |
| void | qev_kill () |
| Unblocks all threads waiting for QEV to exit. More... | |
| 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 running. More... | |
| void | qev_exit () |
| Kill and wait for QEV to exit in one fell swoop. More... | |
| 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. More... | |
| 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. More... | |
| void | qev_listen_unix (const gchar *path) |
| Instruct quick event to create a Unix socket at the given path and listen on it. More... | |
| void | qev_listen_udp (const gchar *ip_address, const guint16 port) |
| Instruct quick event to listen on on a UDP socket for messages. More... | |
| void | qev_chuser (const char *username) |
| Run as this user. | |
| void | qev_setnofile (const gint nofile) |
| Set the limits for the number of open files for this process. More... | |
| void | qev_timer (const qev_cb fn, const guint seconds, const guint ms) |
| Add a callback to be fired on a timer. More... | |
| const gchar * | qev_get_hostname () |
| Get the name of this host. More... | |
| struct QEV_CLIENT * | qev_surrogate_new () |
| Create a surrogate client. More... | |
| GString * | qev_surrogate_flush (struct QEV_CLIENT *surrogate) |
| Steal the entire write buffer from the surrogate client. More... | |
| void | qev_write (struct QEV_CLIENT *client, const gchar *buff, const gsize len) |
| Writes data to the client. More... | |
| void | qev_writef (struct QEV_CLIENT *client, const gchar *format,...) G_GNUC_PRINTF(2 |
| Allows you to use qev_write in a printf() style. More... | |
| void void | qev_close (struct QEV_CLIENT *client, guint reason) |
| Close and free the client when it is safe to do so. More... | |
| gboolean | qev_is_surrogate (struct QEV_CLIENT *client) |
| Determine if a client is a surrogate. More... | |
| gboolean | qev_is_closing (struct QEV_CLIENT *client) |
| Check if a client is closing. More... | |
| void | qev_foreach (qev_client_cb cb, gint threads, void *data) |
| Runs the callback on all clients. More... | |
| struct QEV_CLIENT * | qev_ref (struct QEV_CLIENT *client) |
| Take a reference to the client. | |
| void | qev_unref (struct QEV_CLIENT *client) |
| Release a reference to the client. | |
| void | qev_unref0 (struct QEV_CLIENT **client) |
| Release a reference to the client and set the corresponding memory location to NULL. | |
| void | qev_unref_as_free (void *client_) |
| So that you can use it as a free function without a cast. | |
| void | qev_lock (struct QEV_CLIENT *client) |
| Acquire a lock on a client. More... | |
| void | qev_unlock (struct QEV_CLIENT *client) |
| Release a lock on a client. More... | |
| void | qev_timeout (struct QEV_CLIENT *client, qev_timeout_t **timeout) |
| Set a timeout on a client. More... | |
| void | qev_timeout_clear (qev_timeout_t **timeout) |
| Clear a timeout on a client and release your reference to the timeout. More... | |
| void | qev_chuser (const gchar *username) |
| Change to a different user. More... | |
| void | qev_on_before_run () |
| Before the server is about to run (right before when the QEV threads are set into the event loop), this function will be executed to allow you to create pools, do app init, and all that good stuff. | |
| void | qev_on_open (struct QEV_CLIENT *client) |
| Notification that a new client was accepted. More... | |
| void | qev_on_close (struct QEV_CLIENT *client, guint reason) |
| Notification that a client has closed / been closed. More... | |
| void | qev_on_read (struct QEV_CLIENT *client) |
| A notification that the client has data for reading. More... | |
| void | qev_on_udp (const gchar *msg, const gsize len, const gchar *ip) |
| A notification that there is a new UDP message waiting. More... | |
| void | qev_on_tick () |
| Fired after every iteration of the event loop from every QEV thread. More... | |
| void | qev_on_exit () |
| A notification that QEV is going to shut down. More... | |
| struct QEV_CLIENT * | qev_client_new () |
| Create a new client using whatever memory allocator you wish and sized appropriately for your needs. More... | |
| void | qev_client_free (struct QEV_CLIENT *client) |
| Free the client allocated with qev_client_new(). More... | |
Variables | |
| gint64 | qev_time |
| An approximation of the current time, set from g_get_real_time(), updated at least every 100ms. | |
| gint64 | qev_monotonic |
| An approximate monotonic time, set from g_get_monotonic_time(), updated at least every 100ms. | |
Provides all the qev_* functions that are needed for creating an event loop.
In order to interact with QEV, you're required to create the following functions in your program in a way that QEV can see them: 0) qev_on_before_run(); 1) qev_on_open(struct QEV_CLIENT *client); 2) qev_on_close(struct QEV_CLIENT *client, guint reason); 3) qev_on_read(struct QEV_CLIENT *client); 4) qev_on_udp(const gchar *msg, const gssize len, const gchar *ip); 5) qev_on_tick(); 6) qev_on_exit(); 7) qev_client_new(); 8) qev_client_free(struct QEV_CLIENT *client);
See the function definitions for information about what each function does.
| #define QEV_MS_TO_NSEC | ( | ms | ) | (QEV_MS_TO_USEC(ms) * 1000) |
Convert milliseconds to nanoseconds.
Just so it's easier to read.
| ms | The number of milliseconds to put into nanoseconds. |
| #define QEV_MS_TO_USEC | ( | ms | ) | (ms * 1000) |
Convert milliseconds to microseconds.
Just so it's easier to read.
| ms | The number of milliseconds to put into microseconds. |
| #define QEV_SEC_TO_USEC | ( | secs | ) | QEV_MS_TO_USEC(secs * 1000) |
Convert seconds to microseconds.
Just so it's easier to read.
| secs | The number of seconds to put into microseconds. |
| #define QEV_WAIT_FOR | ( | cond | ) |
Waits for a condition to be true, yielding in the process if it waits too long.
| enum qev_close_reasons |
The reasons a client might be closed.
| void qev_chuser | ( | const gchar * | username | ) |
Change to a different user.
This function will refuse to run as root and return and error if you try to.
| username | The username to run as |
| void qev_client_free | ( | struct QEV_CLIENT * | client | ) |
Free the client allocated with qev_client_new().
This must be used to completely clean up all memory allocated for the client.
| struct QEV_CLIENT* qev_client_new | ( | ) |
Create a new client using whatever memory allocator you wish and sized appropriately for your needs.
The returned client must be zerod out and ready for use.
| void void qev_close | ( | struct QEV_CLIENT * | client, |
| guint | reason | ||
| ) |
Close and free the client when it is safe to do so.
After calling this, no more read callbacks will be fired on this client, and you will receive the close callback only when all the underlying polling mechanisms have synced.
| client | The client to destroy. |
| reason | Why the client is being destroyed. |
| void qev_exit | ( | ) |
Kill and wait for QEV to exit in one fell swoop.
| void qev_foreach | ( | qev_client_cb | cb, |
| gint | threads, | ||
| void * | data | ||
| ) |
Runs the callback on all clients.
| cb | The callback to fire |
| threads | The number of jobs that should be sent to QEV's thread pool. Less than 0 means use the default number of threads (config value "job-threads"). 0 and 1 mean that no job will be sent and this will execute in a single thread. Anything else is just the number of threads. |
| data | Data to give to each callback |
| const gchar* qev_get_hostname | ( | ) |
Get the name of this host.
By default, it uses quick-event's config option "hostname" as the value but falls back to g_get_host_name() in the event that that wasn't set.
| void qev_init | ( | const gchar * | app_name, |
| gchar ** | argv, | ||
| gint | argc | ||
| ) |
Prepares QEV to run.
This function MUST be called before QEV can do anything.
| app_name | The name of your application. Used for stats reporting, monitoring, and the like. Make sure this is a static string, or you're gonna have a bad time. |
| argv | Pretty much main()'s argv |
| argc | main()'s argc |
| gboolean qev_is_closing | ( | struct QEV_CLIENT * | client | ) |
Check if a client is closing.
| client | The client to test |
| gboolean qev_is_surrogate | ( | struct QEV_CLIENT * | client | ) |
Determine if a client is a surrogate.
| client | The client to test |
| void qev_kill | ( | ) |
Unblocks all threads waiting for QEV to exit.
After calling this, at least 1 thread MUST call qev_wait_for_exit() in order for QEV to clean up after itself; typically, the main thread of the application will already be waiting.
| 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.
| ip_address | The IP address to listen on |
| port | The port to listen on |
| 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.
You may pass in both RSA and EC/DSA certificates and keys; each certificate is expected to be a certificate chain that will be given to clients.
| ip_address | The IP address to listen on |
| port | The port to listen on |
| cert_path0 | The path to the server's CA file |
| key_path0 | The path to the server's private key file in PEM |
| cert_path1 | The path to another CA file |
| key_path1 | The path to another private key file in PEM |
| void qev_listen_udp | ( | const gchar * | ip_address, |
| const guint16 | port | ||
| ) |
Instruct quick event to listen on on a UDP socket for messages.
| ip_address | The IP address to listen on |
| port | The port to listen on |
| void qev_listen_unix | ( | const gchar * | path | ) |
Instruct quick event to create a Unix socket at the given path and listen on it.
This is mainly for getting around the TCP/IP limit of 65K clients and is therefore only used for streaming sockets, not datagram.
| path | The path for the socket |
| void qev_lock | ( | struct QEV_CLIENT * | client | ) |
Acquire a lock on a client.
This function will busy wait, while yielding its run time, until it is able to acquire a lock on a client, so you probably shouldn't use this for things like long-blocking IO operations, or other things that take a while.
| client | The client to acquire the lock on. |
| void qev_on_close | ( | struct QEV_CLIENT * | client, |
| guint | reason | ||
| ) |
Notification that a client has closed / been closed.
At this point, you may write a final farewell message to the client so that it knows why it's being killed.
| client | The client that closed. |
| reason | The reason the client closed. |
| void qev_on_exit | ( | ) |
A notification that QEV is going to shut down.
In this function, it's a good idea to tear down ALL parts of your application that call ANY qev_* functions. When this function is called, all QEV threads have exited, so there will be no future callbacks.
| void qev_on_open | ( | struct QEV_CLIENT * | client | ) |
Notification that a new client was accepted.
| client | The client that just opened [transfer-none] |
| void qev_on_read | ( | struct QEV_CLIENT * | client | ) |
A notification that the client has data for reading.
rbuff in the client struct.| client | The client ready for reading [transfer-none] |
| void qev_on_tick | ( | ) |
Fired after every iteration of the event loop from every QEV thread.
This is mainly used to execute periodic events that don't need to be on a timer.
| void qev_on_udp | ( | const gchar * | msg, |
| const gsize | len, | ||
| const gchar * | ip | ||
| ) |
A notification that there is a new UDP message waiting.
| msg | The data that was received |
| len | The length of the data |
| ip | Where the dat came from |
| void qev_setnofile | ( | const gint | nofile | ) |
Set the limits for the number of open files for this process.
It is a fatal error if the OS denies the request.
| GString* qev_surrogate_flush | ( | struct QEV_CLIENT * | surrogate | ) |
Steal the entire write buffer from the surrogate client.
| surrogate | The surrogate to flush from |
| struct QEV_CLIENT* qev_surrogate_new | ( | ) |
Create a surrogate client.
A surrogate client is really just a fake client that has no active socket behind it and is useful for multiplexing a bunch of clients onto a single, real client.
A surrogate client is identical to a real client with the following exceptions:
| void qev_timeout | ( | struct QEV_CLIENT * | client, |
| qev_timeout_t ** | timeout | ||
| ) |
Set a timeout on a client.
Setting a timeout on an already active timeout overwrites the previous one.
| client | The client to set the timeout on |
| timeout | The location where the timeout should be written. |
| void qev_timeout_clear | ( | qev_timeout_t ** | timeout | ) |
Clear a timeout on a client and release your reference to the timeout.
| timeout | The location of the timeout to clear |
| void qev_timer | ( | const qev_cb | fn, |
| const guint | seconds, | ||
| const guint | ms | ||
| ) |
Add a callback to be fired on a timer.
| fn | The function to be called on a timer. |
| seconds | The number of seconds between fn calls |
| ms | The number of milliseconds (in addition to seconds) between fn calls. |
| void qev_unlock | ( | struct QEV_CLIENT * | client | ) |
Release a lock on a client.
| client | The client to release the lock on. |
| 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 running.
| void qev_write | ( | struct QEV_CLIENT * | client, |
| const gchar * | buff, | ||
| const gsize | len | ||
| ) |
Writes data to the client.
| client | The client to write to. |
| buff | The buffer to send to the client |
| len | The amount of data in the buffer |
| void qev_writef | ( | struct QEV_CLIENT * | client, |
| const gchar * | format, | ||
| ... | |||
| ) |
Allows you to use qev_write in a printf() style.
| client | The client to write to |
| format | The string format |
| ... | The parameters for the format |
1.8.6