Path: blob/main/crypto/krb5/src/util/verto/verto.h
34907 views
/*1* Copyright 2011 Red Hat, Inc.2*3* Permission is hereby granted, free of charge, to any person4* obtaining a copy of this software and associated documentation files5* (the "Software"), to deal in the Software without restriction,6* including without limitation the rights to use, copy, modify, merge,7* publish, distribute, sublicense, and/or sell copies of the Software,8* and to permit persons to whom the Software is furnished to do so,9* subject to the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#ifndef VERTO_H_25#define VERTO_H_2627#include <time.h> /* For time_t */28#include <unistd.h> /* For pid_t */2930#ifdef WIN3231#include <windows.h>32typedef HANDLE verto_proc;33typedef DWORD verto_proc_status;34#else35#include <sys/types.h>36typedef pid_t verto_proc;37typedef int verto_proc_status;38#endif3940#define VERTO_SIG_IGN ((verto_callback *) 1)4142#ifdef __cplusplus43extern "C"44{45#endif /* __cplusplus */4647typedef struct verto_ctx verto_ctx;48typedef struct verto_ev verto_ev;4950typedef enum {51VERTO_EV_TYPE_NONE = 0,52VERTO_EV_TYPE_IO = 1,53VERTO_EV_TYPE_TIMEOUT = 1 << 1,54VERTO_EV_TYPE_IDLE = 1 << 2,55VERTO_EV_TYPE_SIGNAL = 1 << 3,56VERTO_EV_TYPE_CHILD = 1 << 457} verto_ev_type;5859typedef enum {60VERTO_EV_FLAG_NONE = 0,61VERTO_EV_FLAG_PERSIST = 1,62VERTO_EV_FLAG_PRIORITY_LOW = 1 << 1,63VERTO_EV_FLAG_PRIORITY_MEDIUM = 1 << 2,64VERTO_EV_FLAG_PRIORITY_HIGH = 1 << 3,65VERTO_EV_FLAG_IO_READ = 1 << 4,66VERTO_EV_FLAG_IO_WRITE = 1 << 5,67VERTO_EV_FLAG_IO_ERROR = 1 << 7,68VERTO_EV_FLAG_IO_CLOSE_FD = 1 << 8,69VERTO_EV_FLAG_REINITIABLE = 1 << 6,70_VERTO_EV_FLAG_MUTABLE_MASK = VERTO_EV_FLAG_PRIORITY_LOW71| VERTO_EV_FLAG_PRIORITY_MEDIUM72| VERTO_EV_FLAG_PRIORITY_HIGH73| VERTO_EV_FLAG_IO_READ74| VERTO_EV_FLAG_IO_WRITE,75_VERTO_EV_FLAG_MAX = VERTO_EV_FLAG_IO_CLOSE_FD76} verto_ev_flag;7778typedef void (verto_callback)(verto_ctx *ctx, verto_ev *ev);7980/**81* Creates a new event context using an optionally specified implementation82* and/or optionally specified required features.83*84* If you are an application that has already decided on using a particular85* event loop implementation, you should not call this function, but instead86* import the verto-NAME.h header and link against the verto-NAME.so, where87* NAME is the implementation you wish to use.88*89* If you are a library, you should generally avoid creating event contexts90* on your own but allow applications to pass in a verto_ctx you can use.91*92* There are two cases where you should use this function. The first is93* where you have a need to choose an implementation at run time, usually94* for testing purposes. The second and more common is when you simply95* wish to remain implementation agnostic. In this later case, you should96* always call like this: verto_new(NULL, ...). This lets verto choose the best97* implementation to use.98*99* If impl is not NULL, a new context is returned which is backed by the100* implementation specified. If the implementation specified is not101* available or if the required types (reqtypes) are not provided by the102* named implementation, NULL is returned. The parameter 'impl' can specify:103* * The full path to an implementation library104* * The name of the implementation library (i.e. - "glib" or "libev")105*106* If impl is NULL, verto will attempt to automatically determine the107* best implementation to use.108*109* First, verto will attempt to use an existing, previously loaded110* implementation. This is handled automatically by internal caching of either111* the first implementation loaded or the one specified by verto_set_default().112*113* Second, verto will attempt to discern if you are already linked to any114* of the supported implementations (to avoid wasting memory by loading115* extra unnecessary libraries). If you are linked to one supported116* implementation, that implementation will be chosen. If you are linked117* to more than one supported implementation one of the ones linked to118* will be chosen, but the order of the particular choice is undefined.119*120* Third, verto will attempt to load the compile-time default, if defined at121* build time and available at runtime.122*123* Last, verto will attempt to load any implementation installed. The specific124* order of this step is undefined.125*126* In all cases above, if the implementation does not support all the specified127* features (reqtypes), it will be skipped and processing will continue from128* where it left off. This means that if verto_new() returns non-NULL it is129* guaranteed to support the features you specified.130*131* @see verto_set_default()132* @param impl The implementation to use, or NULL.133* @param reqtypes A bitwise or'd list of required event type features.134* @return A new verto_ctx, or NULL on error. Call verto_free() when done.135*/136verto_ctx *137verto_new(const char *impl, verto_ev_type reqtypes);138139/**140* Gets the default event context using an optionally specified implementation.141*142* This function is essentially a singleton version of verto_new(). However,143* since this function must return the same loop as the *_default() call of144* the underlying implementation (if such a function exists), it is NOT a145* global singleton, but a per-implementation singleton. For this reason, you146* must call verto_free() when you are done with this loop. Even after calling147* verto_free() on the default verto_ctx, you can safely call verto_default()148* again and receive a new reference to the same (internally default) loop.149*150* In all other respects, verto_default() acts exactly like verto_new().151*152* @see verto_new()153* @see verto_free()154* @param impl The implementation to use, or NULL.155* @param reqtypes A bitwise or'd list of required event type features.156* @return The default verto_ctx, or NULL on error. Call verto_free() when done.157*/158verto_ctx *159verto_default(const char *impl, verto_ev_type reqtypes);160161/**162* Sets the default implementation to use by its name.163*164* This function returns 1 on success and 0 on failure. It can fail for the165* following reasons:166* 1. The default implementation was already set via verto_set_default().167* 2. The implementation specified could not be found.168* 3. The implementation specified didn't support the features specified.169* 4. The impl argument was NULL.170* 5. verto_new() was already called.171* 6. verto_default() was already called.172* 7. verto_new_NAME() was already called.173* 8. verto_default_NAME() was already called.174* 9. verto_convert_NAME() was already called.175*176* @see verto_new()177* @see verto_default()178* @param impl The implementation to use.179* @param reqtypes A bitwise or'd list of required event type features.180* @return The default verto_ctx, or NULL on error. Call verto_free() when done.181*/182int183verto_set_default(const char *impl, verto_ev_type reqtypes);184185/**186* Sets the allocator to use for verto_ctx and verto_ev objects.187*188* If you plan to set the allocator, you MUST call this function before any189* other verto_*() calls.190*191* @see verto_new()192* @see verto_default()193* @see verto_add_io()194* @see verto_add_timeout()195* @see verto_add_idle()196* @see verto_add_signal()197* @see verto_add_child()198* @param resize The allocator to use (behaves like realloc();199* resize(ptr, 0) must free memory at ptr.)200* @param hierarchical Zero if the allocator is not hierarchical201*/202int203verto_set_allocator(void *(*resize)(void *mem, size_t size), int hierarchical);204205/**206* Frees a verto_ctx.207*208* When called on a default verto_ctx, the reference will be freed but the209* internal default loop will still be available via another call to210* verto_default().211*212* @see verto_new()213* @see verto_default()214* @param ctx The verto_ctx to free.215*/216void217verto_free(verto_ctx *ctx);218219/**220* Frees global state.221*222* Remove and free all allocated global state. Call only when no further223* contexts exist and all threads have exited.224*225* @see verto_new()226* @see verto_free()227* @see verto_default()228*/229void230verto_cleanup(void);231232/**233* Run the verto_ctx forever, or at least until verto_break() is called.234*235* @see verto_break()236* @param ctx The verto_ctx to run.237*/238void239verto_run(verto_ctx *ctx);240241/**242* Run the verto_ctx once. May block.243*244* @param ctx The verto_ctx to run once.245*/246void247verto_run_once(verto_ctx *ctx);248249/**250* Exits the currently running verto_ctx.251*252* @see verto_run()253* @param ctx The verto_ctx to exit.254*/255void256verto_break(verto_ctx *ctx);257258/**259* Re-initializes the verto_ctx.260*261* This function deletes all events, except those which have set the262* VERTO_EV_FLAG_REINITIABLE flag. If you fork(), you MUST call this in the263* child process after the fork!264*265* If this function fails it indicates that at least one266* VERTO_EV_FLAG_REINITIABLE event was not rearmed or that ctx was NULL.267*268* @see verto_new()269* @see verto_default()270* @param ctx The verto_ctx to re-initialize.271* @return Non-zero on success, 0 on error.272*/273int274verto_reinitialize(verto_ctx *ctx);275276/**277* Adds a callback executed when a file descriptor is ready to be read/written.278*279* All verto_ev events are automatically freed when their parent verto_ctx is280* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is281* provided, the event will repeat until verto_del() is called. If282* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically283* after its execution. In either case, you may call verto_del() at any time284* to prevent the event from executing.285* If VERTO_EV_FLAG_IO_CLOSE_FD is provided the passed in fd is automatically286* closed when the event is freed with verto_del()287*288* NOTE: On Windows, the underlying select() only works with sockets. As such,289* any attempt to add a non-socket io event on Windows will produce undefined290* results and may even crash.291*292* @see verto_del()293* @param ctx The verto_ctx which will fire the callback.294* @param flags The flags to set (at least one VERTO_EV_FLAG_IO* required).295* @param callback The callback to fire.296* @param fd The file descriptor to watch for reads.297* @return The verto_ev registered with the event context or NULL on error.298*/299verto_ev *300verto_add_io(verto_ctx *ctx, verto_ev_flag flags,301verto_callback *callback, int fd);302303/**304* Adds a callback executed after a period of time.305*306* All verto_ev events are automatically freed when their parent verto_ctx is307* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is308* provided, the event will repeat until verto_del() is called. If309* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically310* after its execution. In either case, you may call verto_del() at any time311* to prevent the event from executing.312*313* @see verto_del()314* @param ctx The verto_ctx which will fire the callback.315* @param flags The flags to set.316* @param callback The callback to fire.317* @param interval Time period to wait before firing (in milliseconds).318* @return The verto_ev registered with the event context.319*/320verto_ev *321verto_add_timeout(verto_ctx *ctx, verto_ev_flag flags,322verto_callback *callback, time_t interval);323324/**325* Adds a callback executed when there is nothing else to do.326*327* All verto_ev events are automatically freed when their parent verto_ctx is328* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is329* provided, the event will repeat until verto_del() is called. If330* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically331* after its execution. In either case, you may call verto_del() at any time332* to prevent the event from executing.333*334* @see verto_del()335* @param ctx The verto_ctx which will fire the callback.336* @param flags The flags to set.337* @param callback The callback to fire.338* @return The verto_ev registered with the event context.339*/340verto_ev *341verto_add_idle(verto_ctx *ctx, verto_ev_flag flags,342verto_callback *callback);343344/**345* Adds a callback executed when a signal is received.346*347* All verto_ev events are automatically freed when their parent verto_ctx is348* freed. You do not need to free them manually. If VERTO_EV_FLAG_PERSIST is349* provided, the event will repeat until verto_del() is called. If350* VERTO_EV_FLAG_PERSIST is not provided, the event will be freed automatically351* after its execution. In either case, you may call verto_del() at any time352* to prevent the event from executing.353*354* NOTE: If you attempt to ignore a signal without the VERTO_EV_FLAG_PERSIST355* flag, this function fails.356*357* NOTE: SIGCHLD is expressly not supported. If you want this notification,358* please use verto_add_child().359*360* WARNNIG: Signal events can only be reliably received in the default verto_ctx361* in some implementations. Attempting to receive signal events in non-default362* loops may result in assert() failures.363*364* WARNING: While verto does its best to protect you from crashes, there is365* essentially no way to do signal events if you mix multiple implementations in366* a single process. Attempting to do so will result in undefined behavior,367* and potentially even a crash. You have been warned.368*369* @see verto_add_child()370* @see verto_repeat()371* @see verto_del()372* @param ctx The verto_ctx which will fire the callback.373* @param flags The flags to set.374* @param callback The callback to fire.375* @param signal The signal to watch for.376* @return The verto_ev registered with the event context.377*/378verto_ev *379verto_add_signal(verto_ctx *ctx, verto_ev_flag flags,380verto_callback *callback, int signal);381382/**383* Adds a callback executed when a child process exits.384*385* This event will be freed automatically after its execution. Due to the386* nature of a process' life-cycle, child events cannot persist (processes only387* exit once). This function returns NULL if you attempt to use388* VERTO_EV_FLAG_PERSIST. You may, of course, call verto_del() at any time to389* prevent the callback from firing.390*391* @see verto_del()392* @param ctx The verto_ctx which will fire the callback.393* @param flags The flags to set.394* @param callback The callback to fire.395* @param child The pid (POSIX) or handle (Win32) of the child to watch for.396* @return The verto_ev registered with the event context.397*/398verto_ev *399verto_add_child(verto_ctx *ctx, verto_ev_flag flags,400verto_callback *callback, verto_proc proc);401402/**403* Sets the private pointer of the verto_ev.404*405* The free callback will be called in two cases:406* 1. When the event is deleted (manually or automatically)407* 2. When verto_set_private() is called again, unless408* free is NULL.409*410* @see verto_get_private()411* @param ev The verto_ev412* @param priv The private value to store413* @param free The callback used to free the data or NULL414*/415void416verto_set_private(verto_ev *ev, void *priv, verto_callback *free);417418/**419* Gets the private pointer of the verto_ev.420*421* @see verto_set_private()422* @param ev The verto_ev423* @return The verto_ev private pointer424*/425void *426verto_get_private(const verto_ev *ev);427428/**429* Gets the type of the verto_ev.430*431* @see verto_add_io()432* @see verto_add_timeout()433* @see verto_add_idle()434* @see verto_add_signal()435* @see verto_add_child()436* @param ev The verto_ev437* @return The verto_ev type438*/439verto_ev_type440verto_get_type(const verto_ev *ev);441442/**443* Gets the flags associated with the given verto_ev.444*445* @see verto_add_io()446* @see verto_add_timeout()447* @see verto_add_idle()448* @see verto_add_signal()449* @see verto_add_child()450* @see verto_set_flags()451* @param ev The verto_ev452* @return The verto_ev type453*/454verto_ev_flag455verto_get_flags(const verto_ev *ev);456457/**458* Sets the flags associated with the given verto_ev.459*460* See _VERTO_EV_FLAG_MUTABLE_MASK for the flags that can be changed461* with this function. All others will be ignored. If the flags specified462* are the same as the flags the event already has, this function is a no-op.463*464* @see verto_add_io()465* @see verto_add_timeout()466* @see verto_add_idle()467* @see verto_add_signal()468* @see verto_add_child()469* @see verto_get_flags()470* @param ev The verto_ev471* @param flags The flags for the event472*/473void474verto_set_flags(verto_ev *ev, verto_ev_flag flags);475476/**477* Gets the file descriptor associated with a read/write verto_ev.478*479* @see verto_add_io()480* @param ev The verto_ev to retrieve the file descriptor from.481* @return The file descriptor, or -1 if not a read/write event.482*/483int484verto_get_fd(const verto_ev *ev);485486/**487* Gets the file descriptor state from when the event fires.488*489* @see verto_add_io()490* @param ev The verto_ev to retrieve the fd state from.491* @return The fd state.492*/493verto_ev_flag494verto_get_fd_state(const verto_ev *ev);495496/**497* Gets the interval associated with a timeout verto_ev.498*499* @see verto_add_timeout()500* @param ev The verto_ev to retrieve the interval from.501* @return The interval, or 0 if not a timeout event.502*/503time_t504verto_get_interval(const verto_ev *ev);505506/**507* Gets the signal associated with a signal verto_ev.508*509* @see verto_add_signal()510* @param ev The verto_ev to retrieve the signal from.511* @return The signal, or -1 if not a signal event.512*/513int514verto_get_signal(const verto_ev *ev);515516/**517* Gets the process associated with a child verto_ev.518*519* @see verto_add_child()520* @param ev The verto_ev to retrieve the process from.521* @return The pid/handle, or 0/NULL if not a child event (POSIX/Win32).522*/523verto_proc524verto_get_proc(const verto_ev *ev);525526/**527* Gets the status of the process which caused this event to fire.528*529* @see verto_add_child()530* @param ev The verto_ev to retrieve the status from.531* @return The pid/handle status.532*/533verto_proc_status534verto_get_proc_status(const verto_ev *ev);535536/**537* Gets the verto_ctx associated with a verto_ev.538*539* This is a borrowed reference, don't attempt to free it!540*541* @param ev The verto_ev to retrieve the verto_ctx from.542* @return The verto_ctx.543*/544verto_ctx *545verto_get_ctx(const verto_ev *ev);546547/**548* Removes an event from from the event context and frees it.549*550* The event and its contents cannot be used after this call.551*552* @see verto_add_io()553* @see verto_add_timeout()554* @see verto_add_idle()555* @see verto_add_signal()556* @see verto_add_child()557* @param ev The event to delete.558*/559void560verto_del(verto_ev *ev);561562/**563* Returns the event types supported by this implementation.564*565* @param ctx The verto_ctx to query.566* @return The event types supported.567*/568verto_ev_type569verto_get_supported_types(verto_ctx *ctx);570571#ifdef __cplusplus572} /* extern "C" */573#endif /* __cplusplus */574#endif /* VERTO_H_ */575576577