libevfibers
|
This file contains all client-visible API functions for working with fibers. More...
#include <unistd.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <assert.h>
#include <ev.h>
#include <evfibers/config.h>
Go to the source code of this file.
Data Structures | |
struct | fbr_id_s |
struct | fbr_context |
Library context structure, should be initialized before any other library calls will be performed. More... | |
struct | fbr_logger |
Logger structure. More... | |
struct | fbr_destructor |
Destructor structure. More... | |
struct | fbr_id_tailq_i |
struct | fbr_ev_base |
Base struct for all events. More... | |
struct | fbr_ev_watcher |
libev watcher event. More... | |
struct | fbr_ev_mutex |
fbr_mutex event. More... | |
struct | fbr_ev_cond_var |
fbr_cond_var event. More... | |
struct | fbr_mutex |
Mutex structure. More... | |
struct | fbr_cond_var |
Conditional variable structure. More... | |
struct | fbr_vrb |
Virtual ring buffer implementation. More... | |
struct | fbr_buffer |
Inter-fiber communication pipe. More... |
Macros | |
#define | FBR_CALL_STACK_SIZE 16 |
Maximum allowed level of fbr_transfer nesting within fibers. | |
#define | FBR_STACK_SIZE (64 * 1024) /* 64 KB */ |
Default stack size for a fiber of 64 KB. | |
#define | fbr_assert(context, expr) |
Fiber version of classic assert. | |
#define | fbr_container_of(ptr, type, member) |
Just for convenience we have container_of macro here. | |
#define | FBR_P struct fbr_context *fctx |
Utility macro for context parameter used in function prototypes. | |
#define | FBR_PU __attribute__((unused)) FBR_P |
Same as FBR_P but with unused attribute. | |
#define | FBR_P_ FBR_P, |
Same as FBR_P, but with comma afterwards for use in functions that accept more that one parameter (which itself is the context pointer). | |
#define | FBR_PU_ __attribute__((unused)) FBR_P_ |
Same as FBR_P_ but unused attribute. | |
#define | FBR_A fctx |
Utility macro for context parameter passing when calling fbr_* functions. | |
#define | FBR_A_ FBR_A, |
Same as FBR_A, but with comma afterwards for invocations of functions that require more that one parameter (which itself is the context pointer). | |
#define | FBR_DESTRUCTOR_INITIALIZER |
#define | fbr_ev_upcast(ptr, type_no_struct) fbr_container_of(ptr, struct type_no_struct, ev_base) |
Convenience macro to save some typing. | |
#define | FBR_MAX_KEY 64 |
Maximum numbef of fiber-local keys allowed. | |
#define | FBR_MAX_FIBER_NAME 64 |
Maximum length of fiber's name. |
Typedefs | |
typedef struct fbr_id_s | fbr_id_t |
Fiber ID type. | |
typedef void(* | fbr_fiber_func_t )(FBR_P_ void *_arg) |
Fiber's ``main'' function type. | |
typedef void(* | fbr_alloc_destructor_func_t )(FBR_P_ void *ptr, void *context) |
(DEPRECATED) Destructor function type for the memory allocated in a fiber. | |
typedef void(* | fbr_log_func_t )(FBR_P_ struct fbr_logger *logger, enum fbr_log_level level, const char *format, va_list ap) |
Logger function type. | |
typedef void(* | fbr_logutil_func_t )(FBR_P_ const char *format,...) |
Logger utility function type. | |
typedef void(* | fbr_destructor_func_t )(FBR_P_ void *arg) |
Destructor function type. | |
typedef unsigned int | fbr_key_t |
Fiber-local data key. |
Enumerations | |
enum | fbr_error_code { FBR_SUCCESS = 0, FBR_EINVAL, FBR_ENOFIBER, FBR_ESYSTEM, FBR_EBUFFERMMAP, FBR_ENOKEY, FBR_EPROTOBUF, FBR_EBUFFERNOSPACE, FBR_EEIO } |
Error codes used within the library. More... | |
enum | fbr_log_level { FBR_LOG_ERROR = 0, FBR_LOG_WARNING, FBR_LOG_NOTICE, FBR_LOG_INFO, FBR_LOG_DEBUG } |
Logging levels. More... | |
enum | fbr_ev_type { FBR_EV_WATCHER = 1, FBR_EV_MUTEX, FBR_EV_COND_VAR, FBR_EV_EIO } |
Type of events supported by the library. More... |
Functions | |
struct fbr_id_s | __attribute__ ((packed)) |
TAILQ_HEAD (fbr_id_tailq, fbr_id_tailq_i) | |
void | fbr_destructor_add (FBR_P_ struct fbr_destructor *dtor) |
Adds destructor to fiber list. | |
void | fbr_destructor_remove (FBR_P_ struct fbr_destructor *dtor, int call) |
Removes destructor from fiber list. | |
void | fbr_ev_watcher_init (FBR_P_ struct fbr_ev_watcher *ev, ev_watcher *w) |
Initializer for libev watcher event. | |
void | fbr_ev_mutex_init (FBR_P_ struct fbr_ev_mutex *ev, struct fbr_mutex *mutex) |
Initializer for mutex event. | |
void | fbr_ev_cond_var_init (FBR_P_ struct fbr_ev_cond_var *ev, struct fbr_cond_var *cond, struct fbr_mutex *mutex) |
Initializer for conditional variable event. | |
int | fbr_ev_wait_one (FBR_P_ struct fbr_ev_base *one) |
Event awaiting function (one event only wrapper). | |
int | fbr_ev_wait (FBR_P_ struct fbr_ev_base *events[]) |
Event awaiting function (generic one). | |
int | fbr_ev_wait_to (FBR_P_ struct fbr_ev_base *events[], ev_tstamp timeout) |
Event awaiting function with timeout. | |
int | fbr_transfer (FBR_P_ fbr_id_t to) |
Transfer of fiber context to another fiber. | |
void | fbr_init (struct fbr_context *fctx, struct ev_loop *loop) |
Initializes the library context. | |
void | fbr_destroy (FBR_P) |
Destroys the library context. | |
void | fbr_enable_backtraces (FBR_P, int enabled) |
Enables/Disables backtrace capturing. | |
const char * | fbr_strerror (FBR_P_ enum fbr_error_code code) |
Analog of strerror but for the library errno. | |
void | fbr_log_e (FBR_P_ const char *format,...) __attribute__((format(printf |
Utility log wrapper. | |
void void | fbr_log_w (FBR_P_ const char *format,...) __attribute__((format(printf |
Utility log wrapper. | |
void void void | fbr_log_n (FBR_P_ const char *format,...) __attribute__((format(printf |
Utility log wrapper. | |
void void void void | fbr_log_i (FBR_P_ const char *format,...) __attribute__((format(printf |
Utility log wrapper. | |
void void void void void | fbr_log_d (FBR_P_ const char *format,...) __attribute__((format(printf |
Utility log wrapper. | |
fbr_id_t | fbr_create (FBR_P_ const char *name, fbr_fiber_func_t func, void *arg, size_t stack_size) |
Creates a new fiber. | |
const char * | fbr_get_name (FBR_P_ fbr_id_t id) |
Retrieve a name of the fiber. | |
int | fbr_set_name (FBR_P_ fbr_id_t id, const char *name) |
Sets a name for the fiber. | |
int | fbr_disown (FBR_P_ fbr_id_t parent) |
Changes parent of current fiber. | |
fbr_id_t | fbr_parent (FBR_P) |
Find out current fiber's parent. | |
int | fbr_reclaim (FBR_P_ fbr_id_t fiber) |
Reclaims a fiber. | |
int | fbr_set_reclaim (FBR_P_ fbr_id_t fiber) |
int | fbr_set_noreclaim (FBR_P_ fbr_id_t fiber) |
int | fbr_want_reclaim (FBR_P_ fbr_id_t fiber) |
int | fbr_is_reclaimed (FBR_P_ fbr_id_t fiber) |
Tests if given fiber is reclaimed. | |
fbr_id_t | fbr_self (FBR_P) |
Returns id of current fiber. | |
int | fbr_key_create (FBR_P_ fbr_key_t *key) |
Fiber-local key creation. | |
int | fbr_key_delete (FBR_P_ fbr_key_t key) |
Fiber-local key deletion. | |
int | fbr_key_set (FBR_P_ fbr_id_t id, fbr_key_t key, void *value) |
Sets fiber-local key data. | |
void * | fbr_key_get (FBR_P_ fbr_id_t id, fbr_key_t key) |
Gets fiber-local key data. | |
void | fbr_yield (FBR_P) |
Yields execution to other fiber. | |
void | fbr_cooperate (FBR_P) |
Yields execution to other fiber returning the execution at the next event loop run. | |
void * | fbr_alloc (FBR_P_ size_t size) |
(DEPRECATED) Allocates memory in current fiber's pool. | |
void | fbr_alloc_set_destructor (FBR_P_ void *ptr, fbr_alloc_destructor_func_t func, void *context) |
(DEPRECATED) Sets destructor for a memory chunk. | |
void * | fbr_calloc (FBR_P_ unsigned int nmemb, size_t size) |
(DEPRECATED) Allocates a set of initialized objects in fiber's pool. | |
void | fbr_free (FBR_P_ void *ptr) |
(DEPRECATED) Explicitly frees allocated memory chunk. | |
void | fbr_free_nd (FBR_P_ void *ptr) |
(DEPRECATED) Explicitly frees allocated memory chunk. | |
int | fbr_fd_nonblock (FBR_P_ int fd) |
Utility function to make file descriptor non-blocking. | |
int | fbr_connect (FBR_P_ int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
Fiber friendly connect wrapper. | |
ssize_t | fbr_read (FBR_P_ int fd, void *buf, size_t count) |
Fiber friendly libc read wrapper. | |
ssize_t | fbr_read_all (FBR_P_ int fd, void *buf, size_t count) |
Even more fiber friendly libc read wrapper. | |
ssize_t | fbr_readline (FBR_P_ int fd, void *buffer, size_t n) |
Utility function to read a line. | |
ssize_t | fbr_write (FBR_P_ int fd, const void *buf, size_t count) |
Fiber friendly libc write wrapper. | |
ssize_t | fbr_write_all (FBR_P_ int fd, const void *buf, size_t count) |
Even more fiber friendly libc write wrapper. | |
ssize_t | fbr_recvfrom (FBR_P_ int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) |
Fiber friendly libc recvfrom wrapper. | |
ssize_t | fbr_recv (FBR_P_ int sockfd, void *buf, size_t len, int flags) |
Fiber friendly libc recv wrapper. | |
ssize_t | fbr_sendto (FBR_P_ int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) |
Fiber friendly libc sendto wrapper. | |
ssize_t | fbr_send (FBR_P_ int sockfd, const void *buf, size_t len, int flags) |
Fiber friendly libc send wrapper. | |
int | fbr_accept (FBR_P_ int sockfd, struct sockaddr *addr, socklen_t *addrlen) |
Fiber friendly libc accept wrapper. | |
ev_tstamp | fbr_sleep (FBR_P_ ev_tstamp seconds) |
Puts current fiber to sleep. | |
void | fbr_dump_stack (FBR_P_ fbr_logutil_func_t log) |
Prints fiber call stack to stderr. | |
void | fbr_mutex_init (FBR_P_ struct fbr_mutex *mutex) |
Initializes a mutex. | |
void | fbr_mutex_lock (FBR_P_ struct fbr_mutex *mutex) |
Locks a mutex. | |
int | fbr_mutex_trylock (FBR_P_ struct fbr_mutex *mutex) |
Tries to locks a mutex. | |
void | fbr_mutex_unlock (FBR_P_ struct fbr_mutex *mutex) |
Unlocks a mutex. | |
void | fbr_mutex_destroy (FBR_P_ struct fbr_mutex *mutex) |
Destroys a mutex. | |
void | fbr_cond_init (FBR_P_ struct fbr_cond_var *cond) |
Initializes a conditional variable. | |
void | fbr_cond_destroy (FBR_P_ struct fbr_cond_var *cond) |
Destroys a conditional variable. | |
int | fbr_cond_wait (FBR_P_ struct fbr_cond_var *cond, struct fbr_mutex *mutex) |
Waits until condition is met. | |
void | fbr_cond_broadcast (FBR_P_ struct fbr_cond_var *cond) |
Broadcasts a signal to all fibers waiting for condition. | |
void | fbr_cond_signal (FBR_P_ struct fbr_cond_var *cond) |
Signals to first fiber waiting for a condition. | |
int | fbr_vrb_init (struct fbr_vrb *vrb, size_t size, const char *file_pattern) |
Initializes memory mappings. | |
void | fbr_vrb_destroy (struct fbr_vrb *vrb) |
Destroys mappings. | |
int | fbr_vrb_resize_do (struct fbr_vrb *vrb, size_t new_size, const char *file_pattern) |
int | fbr_buffer_init (FBR_P_ struct fbr_buffer *buffer, size_t size) |
Initializes a circular buffer with pipe semantics. | |
void | fbr_buffer_destroy (FBR_P_ struct fbr_buffer *buffer) |
Destroys a circular buffer. | |
void * | fbr_buffer_alloc_prepare (FBR_P_ struct fbr_buffer *buffer, size_t size) |
Prepares a chunk of memory to be committed to buffer. | |
void | fbr_buffer_alloc_commit (FBR_P_ struct fbr_buffer *buffer) |
Commits a chunk of memory to the buffer. | |
void | fbr_buffer_alloc_abort (FBR_P_ struct fbr_buffer *buffer) |
Aborts a chunk of memory in the buffer. | |
void * | fbr_buffer_read_address (FBR_P_ struct fbr_buffer *buffer, size_t size) |
Aborts a chunk of memory in the buffer. | |
void | fbr_buffer_read_advance (FBR_P_ struct fbr_buffer *buffer) |
Confirms a read of chunk of memory in the buffer. | |
void | fbr_buffer_read_discard (FBR_P_ struct fbr_buffer *buffer) |
Discards a read of chunk of memory in the buffer. | |
int | fbr_buffer_resize (FBR_P_ struct fbr_buffer *buffer, size_t size) |
Resizes the buffer. | |
void * | fbr_get_user_data (FBR_P_ fbr_id_t id) |
Gets fiber user data pointer. | |
int | fbr_set_user_data (FBR_P_ fbr_id_t id, void *data) |
Sets fiber user data pointer. | |
pid_t | fbr_popen3 (FBR_P_ const char *filename, char *const argv[], char *const envp[], const char *working_dir, int *stdin_w_ptr, int *stdout_r_ptr, int *stderr_r_ptr) |
int | fbr_waitpid (FBR_P_ pid_t pid) |
int | fbr_system (FBR_P_ const char *filename, char *const argv[], char *const envp[], const char *working_dir) |
Variables | |
uint64_t | g |
void * | p |
const fbr_id_t | FBR_ID_NULL |
enum fbr_error_code | __attribute__ |
This file contains all client-visible API functions for working with fibers.
Definition in file fiber.h.
#define fbr_assert | ( | context, | |
expr | |||
) |
#define fbr_container_of | ( | ptr, | |
type, | |||
member | |||
) |
#define FBR_DESTRUCTOR_INITIALIZER |
#define fbr_ev_upcast | ( | ptr, | |
type_no_struct | |||
) | fbr_container_of(ptr, struct type_no_struct, ev_base) |
Convenience macro to save some typing.
Allows you to cast fbr_ev_base to some other event struct via fbr_container_of magic.
typedef void(* fbr_alloc_destructor_func_t)(FBR_P_ void *ptr, void *context) |
(DEPRECATED) Destructor function type for the memory allocated in a fiber.
[in] | ptr | memory pointer for memory to be destroyed |
[in] | context | user data pointer passed via fbr_alloc_set_destructor |
One can attach a destructor to a piece of memory allocated in a fiber. It will be called whenever memory is freed with original pointer allocated along with a user context pointer passed to it.
typedef void(* fbr_destructor_func_t)(FBR_P_ void *arg) |
Destructor function type.
[in] | arg | user-defined data argument |
This function gets called when containing fiber dies or destructor is removed with call flag set to 1.
typedef void(* fbr_fiber_func_t)(FBR_P_ void *_arg) |
Fiber's ``main'' function type.
Fiber main function takes only one parameter — the context. If you need to pass more context information, you shall embed fbr_context into any structure of your choice and calculate the base pointer using container_of macro.
typedef unsigned int fbr_key_t |
Fiber-local data key.
typedef void(* fbr_log_func_t)(FBR_P_ struct fbr_logger *logger, enum fbr_log_level level, const char *format, va_list ap) |
Logger function type.
[in] | logger | currently configured logger |
[in] | level | log level of message |
[in] | format | printf-compatible format string |
[in] | ap | variadic argument list This function should log the message if log level suits the one configured in a non-blocking manner (i.e. it should not synchronously write it to disk). |
typedef void(* fbr_logutil_func_t)(FBR_P_ const char *format,...) |
Logger utility function type.
[in] | format | printf-compatible format string |
This function wraps logger function invocation.
enum fbr_error_code |
Error codes used within the library.
These constants are returned via f_errno member of fbr_context struct.
enum fbr_ev_type |
Type of events supported by the library.
FBR_EV_WATCHER |
libev watcher event |
FBR_EV_MUTEX |
fbr_mutex event |
FBR_EV_COND_VAR |
fbr_cond_var event |
FBR_EV_EIO |
libeio event |
enum fbr_log_level |
int fbr_accept | ( | FBR_P_ int | sockfd, |
struct sockaddr * | addr, | ||
socklen_t * | addrlen | ||
) |
Fiber friendly libc accept wrapper.
[in] | sockfd | file descriptor to accept on |
[in] | addr | client address |
[in] | addrlen | size of addr |
This function is used to accept a connection on a listening socket.
Possible errno values are described in accept man page. The only special case is EINTR which is handled internally and is returned to the caller only in case when non-root fiber called the fiber sitting in fbr_accept.
void* fbr_alloc | ( | FBR_P_ size_t | size | ) |
(DEPRECATED) Allocates memory in current fiber's pool.
[in] | size | size of the requested memory block |
When a fiber is reclaimed, this memory will be freed. Prior to that a destructor will be called if any specified.
void fbr_alloc_set_destructor | ( | FBR_P_ void * | ptr, |
fbr_alloc_destructor_func_t | func, | ||
void * | context | ||
) |
(DEPRECATED) Sets destructor for a memory chunk.
[in] | ptr | address of a memory chunk |
[in] | func | destructor function |
[in] | context | user supplied context pointer |
Setting new destructor simply changes it without calling old one or queueing them.
You can allocate 0 sized memory chunk and never free it just for the purpose of calling destructor with some context when fiber is reclaimed. This way you can for example close some file descriptors or do some other required cleanup.
void fbr_buffer_alloc_abort | ( | FBR_P_ struct fbr_buffer * | buffer | ) |
Aborts a chunk of memory in the buffer.
[in] | buffer | a pointer to fbr_buffer |
This function aborts prepared chunk of memory previously reserved. It will not be committed and the next fiber may reuse it for it's own purposes.
void fbr_buffer_alloc_commit | ( | FBR_P_ struct fbr_buffer * | buffer | ) |
Commits a chunk of memory to the buffer.
[in] | buffer | a pointer to fbr_buffer |
This function commits a chunk of memory previously reserved.
void* fbr_buffer_alloc_prepare | ( | FBR_P_ struct fbr_buffer * | buffer, |
size_t | size | ||
) |
Prepares a chunk of memory to be committed to buffer.
[in] | buffer | a pointer to fbr_buffer |
[in] | size | required size |
This function reserves a chunk of memory (or waits until there is one available, blocking current fiber) and returns pointer to it.
A fiber trying to reserve a chunk of memory after some other fiber already reserved it leads to the former fiber being blocked until the latter one commits or aborts.
void fbr_buffer_destroy | ( | FBR_P_ struct fbr_buffer * | buffer | ) |
Destroys a circular buffer.
[in] | buffer | a pointer to fbr_buffer to free |
This unmaps all mmaped memory for the buffer. It does not do any fancy stuff like waiting until buffer is empty etc., it just frees it.
int fbr_buffer_init | ( | FBR_P_ struct fbr_buffer * | buffer, |
size_t | size | ||
) |
Initializes a circular buffer with pipe semantics.
[in] | buffer | fbr_buffer structure to initialize |
[in] | size | size hint for the buffer |
This allocates a buffer with pipe semantics: you can write into it and later read what you have written. The buffer will occupy size rounded up to page size in physical memory, while occupying twice this size in virtual process memory due to usage of two mirrored adjacent mmaps.
void* fbr_buffer_read_address | ( | FBR_P_ struct fbr_buffer * | buffer, |
size_t | size | ||
) |
Aborts a chunk of memory in the buffer.
[in] | buffer | a pointer to fbr_buffer |
[in] | size | number of bytes required |
This function reserves (or waits till data is available, blocking current fiber) a chunk of memory for reading. While a chunk of memory is reserved for reading no other fiber can read from this buffer blocking until current read is advanced or discarded.
void fbr_buffer_read_advance | ( | FBR_P_ struct fbr_buffer * | buffer | ) |
Confirms a read of chunk of memory in the buffer.
[in] | buffer | a pointer to fbr_buffer |
This function confirms that bytes obtained with fbr_buffer_read_address are read and no other fiber will be able to read them.
void fbr_buffer_read_discard | ( | FBR_P_ struct fbr_buffer * | buffer | ) |
Discards a read of chunk of memory in the buffer.
[in] | buffer | a pointer to fbr_buffer |
This function discards bytes obtained with fbr_buffer_read_address. Next fiber trying to read something from a buffer may obtain those bytes.
int fbr_buffer_resize | ( | FBR_P_ struct fbr_buffer * | buffer, |
size_t | size | ||
) |
Resizes the buffer.
[in] | buffer | a pointer to fbr_buffer |
[in] | size | a new buffer length |
This function allocates new memory mapping of sufficient size and copies the content of a buffer into it. Old mapping is destroyed.
This operation is expensive and involves several syscalls, so it is beneficiary to allocate a buffer of siffucuent size from the start.
This function acquires both read and write mutex, and may block until read or write operation has finished.
void* fbr_calloc | ( | FBR_P_ unsigned int | nmemb, |
size_t | size | ||
) |
(DEPRECATED) Allocates a set of initialized objects in fiber's pool.
[in] | nmemb | number of members |
[in] | size | size of a single member |
Same as fbr_alloc called with nmemb multiplied by size.
void fbr_cond_broadcast | ( | FBR_P_ struct fbr_cond_var * | cond | ) |
Broadcasts a signal to all fibers waiting for condition.
All fibers waiting for a condition will be added to run queue (and will eventually be run, one per event loop iteration).
void fbr_cond_destroy | ( | FBR_P_ struct fbr_cond_var * | cond | ) |
Destroys a conditional variable.
This just frees used resources. No signals are sent to waiting fibers.
void fbr_cond_init | ( | FBR_P_ struct fbr_cond_var * | cond | ) |
Initializes a conditional variable.
Conditional variable is useful primitive for fiber synchronisation. A set of fibers may be waiting until certain condition is met. Another fiber can trigger this condition for one or all waiting fibers.
void fbr_cond_signal | ( | FBR_P_ struct fbr_cond_var * | cond | ) |
Signals to first fiber waiting for a condition.
Exactly one fiber (first one) waiting for a condition will be added to run queue (and will eventually be run, one per event loop iteration).
int fbr_cond_wait | ( | FBR_P_ struct fbr_cond_var * | cond, |
struct fbr_mutex * | mutex | ||
) |
Waits until condition is met.
Current fiber is suspended until a signal is sent via fbr_cond_signal or fbr_cond_broadcast to the corresponding conditional variable.
A mutex must be acquired by the calling fiber prior to waiting for a condition. Internally mutex is released and reacquired again before returning. Upon successful return calling fiber will hold the mutex.
int fbr_connect | ( | FBR_P_ int | sockfd, |
const struct sockaddr * | addr, | ||
socklen_t | addrlen | ||
) |
Fiber friendly connect wrapper.
[in] | sockfd | - socket file descriptor |
[in] | addr | - pointer to struct sockaddr, containing connection details |
[in] | length | of struct sockaddr |
Connect wrapper, that connects the socket referred to by the file descriptor sockfd to the address specified by addr. starting at buf. Calling fiber will be blocked until sockfd is connected or error is occured
Possible errno values are described in connect man page. The only special case is EINPROGRESS which is handled internally.
void fbr_cooperate | ( | FBR_P | ) |
Yields execution to other fiber returning the execution at the next event loop run.
Useful inside of some busy loop with lots of iterations to play nicely with other fibers which might start starving on the execution time.
fbr_id_t fbr_create | ( | FBR_P_ const char * | name, |
fbr_fiber_func_t | func, | ||
void * | arg, | ||
size_t | stack_size | ||
) |
Creates a new fiber.
[in] | name | fiber name, used for identification it backtraces, etc. |
[in] | func | function used as a fiber's ``main''. |
[in] | stack_size | stack size (0 for default). |
[in] | arg | user supplied argument to a fiber. |
The created fiber is not running in any shape or form, it's just created and is ready to be launched.
Stack is anonymously mmaped so it should not occupy all the required space straight away. Adjust stack size only when you know what you are doing!
Allocated stacks are registered as stacks via valgrind client request mechanism, so it's generally valgrind friendly and should not cause any noise.
Fibers are organized in a tree. Child nodes are attached to a parent whenever the parent is creating them. This tree is used primarily for automatic reclaim of child fibers.
void fbr_destroy | ( | FBR_P | ) |
Destroys the library context.
All created fibers are reclaimed and all of the memory is freed. Stopping the event loop is user's responsibility.
void fbr_destructor_add | ( | FBR_P_ struct fbr_destructor * | dtor | ) |
Adds destructor to fiber list.
[in] | dtor | destructor to register |
This function registers a destructor. User must guarantee that destructor object stays alive until fiber is reclaimed or destructor is removed, whichever comes first.
void fbr_destructor_remove | ( | FBR_P_ struct fbr_destructor * | dtor, |
int | call | ||
) |
Removes destructor from fiber list.
[in] | dtor | destructor to unregister |
[in] | call | flag indicating if destructor needs to be called |
This function unregisters a destructor. User may specify a flag for destructor function to be called.
Changes parent of current fiber.
[in] | parent | new parent fiber |
This function allows you to change fiber's parent. You needs to pass valid id or 0 to indicate the root fiber.
This might be useful when some fiber A creates another fiber B that should survive it's parent being reclaimed, or vice versa, some fiber A needs to be reclaimed with fiber B albeit B is not A's parent.
Root fiber is reclaimed only when library context is destroyed.
void fbr_dump_stack | ( | FBR_P_ fbr_logutil_func_t | log | ) |
void fbr_enable_backtraces | ( | FBR_P | , |
int | enabled | ||
) |
Enables/Disables backtrace capturing.
[in] | enabled | are backtraces enabled? |
The library tries to capture backtraces at certain points which may help when debugging obscure problems. For example it captures the backtrace whenever a fiber is reclaimed and when one tries to call it dumps out the backtrace showing where was it reclaimed. But these cost quite a bit of cpu and are disabled by default.
void fbr_ev_cond_var_init | ( | FBR_P_ struct fbr_ev_cond_var * | ev, |
struct fbr_cond_var * | cond, | ||
struct fbr_mutex * | mutex | ||
) |
Initializer for conditional variable event.
This functions properly initializes fbr_ev_cond_var struct. You should not do it manually.
void fbr_ev_mutex_init | ( | FBR_P_ struct fbr_ev_mutex * | ev, |
struct fbr_mutex * | mutex | ||
) |
Initializer for mutex event.
This functions properly initializes fbr_ev_mutex struct. You should not do it manually.
int fbr_ev_wait | ( | FBR_P_ struct fbr_ev_base * | events[] | ) |
Event awaiting function (generic one).
[in] | events | array of event base pointers |
This function waits until any event from events array arrives. Only one event can arrive at a time. It returns a pointer to the same event that was passed in events array.
int fbr_ev_wait_one | ( | FBR_P_ struct fbr_ev_base * | one | ) |
Event awaiting function (one event only wrapper).
[in] | one | the event base pointer of the event to wait for |
This functions wraps fbr_ev_wait passing only one event to it.
int fbr_ev_wait_to | ( | FBR_P_ struct fbr_ev_base * | events[], |
ev_tstamp | timeout | ||
) |
Event awaiting function with timeout.
[in] | events | array of event base pointers |
[in] | timeout | in seconds to wait for the events |
This function is a convenient wrapper around fbr_ev_wait, it just creates a timer watcher and makes new events array with the timer watcher included. Timer event is not counted in the number of returned events.
void fbr_ev_watcher_init | ( | FBR_P_ struct fbr_ev_watcher * | ev, |
ev_watcher * | w | ||
) |
Initializer for libev watcher event.
This functions properly initializes fbr_ev_watcher struct. You should not do it manually.
int fbr_fd_nonblock | ( | FBR_P_ int | fd | ) |
void fbr_free | ( | FBR_P_ void * | ptr | ) |
(DEPRECATED) Explicitly frees allocated memory chunk.
[in] | ptr | chunk address |
Explicitly frees a fiber pool chunk calling the destructor if any.
void fbr_free_nd | ( | FBR_P_ void * | ptr | ) |
(DEPRECATED) Explicitly frees allocated memory chunk.
[in] | ptr | chunk address |
Explicitly frees a fiber pool chunk without calling the destructor.
Retrieve a name of the fiber.
[in] | id | identificator of a fiber |
The name is located in the statically allocated buffer of size FBR_MAX_FIBER_NAME.
Don't try to free it!
Gets fiber user data pointer.
[in] | id | fiber id |
This function allows you to retrieve user data pointer.
void fbr_init | ( | struct fbr_context * | fctx, |
struct ev_loop * | loop | ||
) |
Initializes the library context.
[in] | fctx | pointer to the user allocated fbr_context. |
[in] | loop | pointer to the user supplied libev loop. |
It's user's responsibility to allocate fbr_context structure and create and run the libev event loop.
Tests if given fiber is reclaimed.
[in] | fiber | fiber pointer |
void void void void void fbr_log_d | ( | FBR_P_ const char * | format, |
... | |||
) |
Utility log wrapper.
Wraps logv function of type fbr_log_func_t located in fbr_logger with log level of FBR_LOG_DEBUG. Follows printf semantics of format string and variadic argument list.
void fbr_log_e | ( | FBR_P_ const char * | format, |
... | |||
) |
Utility log wrapper.
Wraps logv function of type fbr_log_func_t located in fbr_logger with log level of FBR_LOG_ERROR. Follows printf semantics of format string and variadic argument list.
void void void void fbr_log_i | ( | FBR_P_ const char * | format, |
... | |||
) |
Utility log wrapper.
Wraps logv function of type fbr_log_func_t located in fbr_logger with log level of FBR_LOG_INFO. Follows printf semantics of format string and variadic argument list.
void void void fbr_log_n | ( | FBR_P_ const char * | format, |
... | |||
) |
Utility log wrapper.
Wraps logv function of type fbr_log_func_t located in fbr_logger with log level of FBR_LOG_NOTICE. Follows printf semantics of format string and variadic argument list.
void void fbr_log_w | ( | FBR_P_ const char * | format, |
... | |||
) |
Utility log wrapper.
Wraps logv function of type fbr_log_func_t located in fbr_logger with log level of FBR_LOG_WARNING. Follows printf semantics of format string and variadic argument list.
Destroys a mutex.
[in] | mutex | pointer to mutex |
Frees used resources. It does not unlock the mutex.
Initializes a mutex.
[in] | mutex | a mutex structure to initialize |
Mutexes are helpful when your fiber has a critical code section including several fbr_* calls. In this case execution of multiple copies of your fiber may get mixed up.
Locks a mutex.
[in] | mutex | pointer to a mutex |
Attempts to lock a mutex. If mutex is already locked then the calling fiber is suspended until the mutex is eventually freed.
Tries to locks a mutex.
[in] | mutex | pointer to a mutex |
Attempts to lock a mutex. Returns immediately despite of locking being successful or not.
Unlocks a mutex.
[in] | mutex | pointer to a mutex |
Unlocks the given mutex. An other fiber that is waiting for it (if any) will be called upon next libev loop iteration.
Find out current fiber's parent.
This function allows you to find out what fiber is considered to be parent for the current one.
ssize_t fbr_read | ( | FBR_P_ int | fd, |
void * | buf, | ||
size_t | count | ||
) |
Fiber friendly libc read wrapper.
[in] | fd | file descriptor to read from |
[in] | buf | pointer to some user-allocated buffer |
[in] | count | maximum number of bytes to read |
Attempts to read up to count bytes from file descriptor fd into the buffer starting at buf. Calling fiber will be blocked until something arrives at fd.
Possible errno values are described in read man page. The only special case is EINTR which is handled internally and is returned to the caller only in case when non-root fiber called the fiber waiting in fbr_read.
ssize_t fbr_read_all | ( | FBR_P_ int | fd, |
void * | buf, | ||
size_t | count | ||
) |
Even more fiber friendly libc read wrapper.
[in] | fd | file descriptor to read from |
[in] | buf | pointer to some user-allocated buffer |
[in] | count | desired number of bytes to read |
Attempts to read exactly count bytes from file descriptor fd into the buffer starting at buf. Calling fiber will be blocked until the required amount of data or EOF arrive at fd. If latter occurs too early returned number of bytes will be less that required.
Possible errno values are described in read man page. Unlike fbr_read this function will never return -1 with EINTR and will silently ignore any attempts to call this fiber from other non-root fibers (call infos are still queued if the called desired to do so).
ssize_t fbr_readline | ( | FBR_P_ int | fd, |
void * | buffer, | ||
size_t | n | ||
) |
Utility function to read a line.
[in] | fd | file descriptor to read from |
[in] | buffer | pointer to some user-allocated buffer |
[in] | n | maximum number of bytes to read |
Attempts to read at most count bytes from file descriptor fd into the buffer starting at buf, but stops if newline is encountered. Calling fiber will be blocked until the required amount of data, EOF or newline arrive at fd.
Possible errno values are described in read man page. As with fbr_read_all this function will never return -1 with EINTR.
Reclaims a fiber.
[in] | fiber | fiber pointer |
Fibers are never destroyed, but reclaimed. Reclamation frees some resources like call lists and memory pools immediately while keeping fiber structure itself and its stack as is. Reclaimed fiber is prepended to the reclaimed fiber list and will be served as a new one whenever next fbr_create is called. Fiber is prepended because it is warm in terms of cpu cache and its use might be faster than any other fiber in the list.
When you have some reclaimed fibers in the list, reclaiming and creating are generally cheap operations.
ssize_t fbr_recv | ( | FBR_P_ int | sockfd, |
void * | buf, | ||
size_t | len, | ||
int | flags | ||
) |
Fiber friendly libc recv wrapper.
[in] | sockfd | file descriptor to read from |
[in] | buf | pointer to some user-allocated buffer |
[in] | len | maximum number of bytes to read |
[in] | flags | just flags, see man recvfrom for details |
This function is used to receive messages from a socket.
Possible errno values are described in recv man page.
ssize_t fbr_recvfrom | ( | FBR_P_ int | sockfd, |
void * | buf, | ||
size_t | len, | ||
int | flags, | ||
struct sockaddr * | src_addr, | ||
socklen_t * | addrlen | ||
) |
Fiber friendly libc recvfrom wrapper.
[in] | sockfd | file descriptor to read from |
[in] | buf | pointer to some user-allocated buffer |
[in] | len | maximum number of bytes to read |
[in] | flags | just flags, see man recvfrom for details |
[in] | src_addr | source address |
[in] | addrlen | size of src_addr |
This function is used to receive messages from a socket.
Possible errno values are described in recvfrom man page. The only special case is EINTR which is handled internally and is returned to the caller only in case when non-root fiber called the fiber sitting in fbr_recvfrom.
ssize_t fbr_send | ( | FBR_P_ int | sockfd, |
const void * | buf, | ||
size_t | len, | ||
int | flags | ||
) |
Fiber friendly libc send wrapper.
[in] | sockfd | file descriptor to write to |
[in] | buf | pointer to some user-allocated buffer |
[in] | len | maximum number of bytes to write |
[in] | flags | just flags, see man sendto for details |
This function is used to send messages to a socket.
ssize_t fbr_sendto | ( | FBR_P_ int | sockfd, |
const void * | buf, | ||
size_t | len, | ||
int | flags, | ||
const struct sockaddr * | dest_addr, | ||
socklen_t | addrlen | ||
) |
Fiber friendly libc sendto wrapper.
[in] | sockfd | file descriptor to write to |
[in] | buf | pointer to some user-allocated buffer |
[in] | len | maximum number of bytes to write |
[in] | flags | just flags, see man sendto for details |
[in] | dest_addr | destination address |
[in] | addrlen | size of dest_addr |
This function is used to send messages to a socket.
Possible errno values are described in sendto man page. The only special case is EINTR which is handled internally and is returned to the caller only in case when non-root fiber called the fiber sitting in fbr_sendto.
Sets a name for the fiber.
[in] | id | identificator of a fiber |
[in] | name | new name for a fiber |
The name is located in the statically allocated buffer of size FBR_MAX_FIBER_NAME. If your name does not fit, it will be trimmed.
Sets fiber user data pointer.
[in] | id | fiber id |
[in] | data | pointer to user data |
This function allows you to extend fiber with some user structure.
ev_tstamp fbr_sleep | ( | FBR_P_ ev_tstamp | seconds | ) |
Puts current fiber to sleep.
[in] | seconds | maximum number of seconds to sleep |
This function is used to put current fiber into sleep. It will wake up after the desired time has passed or earlier if some other fiber has called it.
const char* fbr_strerror | ( | FBR_P_ enum fbr_error_code | code | ) |
Analog of strerror but for the library errno.
[in] | code | Error code to describe |
Transfer of fiber context to another fiber.
[in] | to | callee id |
This function transfers the execution context to other fiber. It returns as soon as the called fiber yields. In case of error it returns immediately.
void fbr_vrb_destroy | ( | struct fbr_vrb * | vrb | ) |
Destroys mappings.
[in] | vrb | a pointer to fbr_vrb |
This function unmaps all the mappings done by fbr_vrb_init.
int fbr_vrb_init | ( | struct fbr_vrb * | vrb, |
size_t | size, | ||
const char * | file_pattern | ||
) |
Initializes memory mappings.
[in] | vrb | a pointer to fbr_vrb |
[in] | size | length of the data |
[in] | file_pattern | file name patterm for underlying mmap storage |
This function mmaps adjacent virtual memory regions of required size which correspond to the same physical memory region. Also it adds two page-sized regions on the left and on the right with PROT_NONE access as a guards.
It does mmaps on the same file, which is unlinked and closed afterwards, so it will not pollute file descriptor space of a process and the filesystem.
ssize_t fbr_write | ( | FBR_P_ int | fd, |
const void * | buf, | ||
size_t | count | ||
) |
Fiber friendly libc write wrapper.
[in] | fd | file descriptor to write to |
[in] | buf | pointer to some user-allocated buffer |
[in] | count | maximum number of bytes to write |
Attempts to write up to count bytes to file descriptor fd from the buffer starting at buf. Calling fiber will be blocked until the data is written.
Possible errno values are described in write man page. The only special case is EINTR which is handled internally and is returned to the caller only in case when non-root fiber called the fiber sitting in fbr_write.
ssize_t fbr_write_all | ( | FBR_P_ int | fd, |
const void * | buf, | ||
size_t | count | ||
) |
Even more fiber friendly libc write wrapper.
[in] | fd | file descriptor to write to |
[in] | buf | pointer to some user-allocated buffer |
[in] | count | desired number of bytes to write |
Attempts to write exactly count bytes to file descriptor fd from the buffer starting at buf. Calling fiber will be blocked until the required amount of data is written to fd.
Possible errno values are described in write man page. Unlike fbr_write this function will never return -1 with EINTR and will silently ignore any attempts to call this fiber from other non-root fibers (call infos are still queued if the called desired to do so).
void fbr_yield | ( | FBR_P | ) |
Yields execution to other fiber.
When a fiber is waiting for some incoming event — it should yield. This will pop current fiber from the fiber stack and transfer the execution context to the next fiber from the stack making that fiber a new current one.
It loops through all fibers subscribed to specified multicast group id.