"Original" Libevent2 Lock related code

Source: Internet
Author: User


in the bufferevent-internal.h
" bufferevent lock operation function "
/** Internal:given a bufferevent, return its corresponding bufferevent_private. *///internal use of macros//through the bufferevent structure to get its own bufferevent_private structure # # Bev_upcast (b) Evutil_upcast ((b), struct BUFFEREVENT_ Private, Bev) #ifdef _event_disable_thread_support    #define Bev_lock (b) _evutil_nil_stmt    #define Bev_unlock (b ) _evutil_nil_stmt#else/** Internal:grab The lock (if any) on a bufferevent *///internal use macro//To Bufferevent Lock # define Bev_lock (b) Do {    struct bufferevent_private *locking =  Bev_upcast (b);    Evlock_lock (locking->lock, 0);} while (0)/** Internal:release the lock (if any) on a bufferevent *///internal use macro//to Bufferevent Unlock # define Bev_unlock (b) do { C5/>struct bufferevent_private *locking =  Bev_upcast (b);    Evlock_unlock (locking->lock, 0);} while (0) #endif

in the bufferevent.c
" Bufferevent's lock enable "
Create bufferevent for Bufferevent_private and initialize the internal structure Intbufferevent_init_common (struct bufferevent_private *bufev_private ,    struct event_base *base, const struct Bufferevent_ops *ops, enum bufferevent_options options) {... #ifndef _event_ disable_thread_support//if the thread supports if compile-time    (Options & Bev_opt_threadsafe) {///and Bufferevent also enables the thread to support        if ( Bufferevent_enable_locking (Bufev, NULL) < 0) {/            * cleanup *            /Evbuffer_free (bufev->input);            Evbuffer_free (bufev->output);            Bufev->input = NULL;            Bufev->output = NULL;            return-1;        }    } #endif ...}

"bufferevent lock Settings "
Set lock//Note For each structure associated with bufferevent: All structures share lockintbufferevent_enable_locking (struct bufferevent *bufev, void *lock) {    #ifdef _event_disable_thread_support return-1; #else struct bufferevent *underlying;    First make sure that the Bufev belongs to the bufferevent_private without lock if (Bev_upcast (Bufev)->lock) return-1;    Returns NULL underlying = Bufferevent_get_underlying (Bufev) If bufferevent is a socket or pair type; If lock is not provided externally, but the Bufev contains the underlying bufferevent//and the lock variable exists in the bufferevent_private of the underlying bufferevent//The lock is used directly as B Ufferevent Lock if (!lock && underlying && bev_upcast (underlying)->lock) {lock = Bev_upcast (UN        derlying)->lock;        Bev_upcast (BUFEV)->lock = lock;    Bev_upcast (bufev)->own_lock = 0; The else if (!lock) {//external lock is not provided and the underlying also has no locks available//The lock is assigned as Bufferevent Evthread_alloc_lock (lock, Evthread        _locktype_recursive);        if (!lock) return-1;     Bev_upcast (BUFEV)->lock = lock;   Bev_upcast (Bufev)->own_lock = 1;        } else {//externally provides lock for direct use of Bev_upcast (BUFEV)->lock = lock;    Bev_upcast (bufev)->own_lock = 0;    }//Set the lock evbuffer_enable_locking (Bufev->input, lock) for input and output buffers;    Evbuffer_enable_locking (Bufev->output, lock); if (underlying &&!)    Bev_upcast (underlying)->lock) bufferevent_enable_locking (underlying, lock); return 0; #endif}

in the buffer.c
"evbuffer lock Settings "
Set lockintevbuffer_enable_locking (struct Evbuffer *buf, void *lock) for evbuffer {#ifdef _event_disable_thread_support< c5/>return-1; #else    //If lock is present in Evbuffer, the direct return to    if (buf->lock)        return-1;    if (!lock) {        Evthread_alloc_lock (lock, evthread_locktype_recursive);        if (!lock)            return-1;        Buf->lock = lock;        Buf->own_lock = 1;    } else {        Buf->lock = lock;        Buf->own_lock = 0;    }    return 0; #endif}

in the evbuffer-internal.h
"lock definition in Evbuffer "
struct Evbuffer {... #ifndef _event_disable_thread_support/** A lock used to mediate access to this buffer. */    void *lo ck; #endif ...}

in the event-internal.h
"lock definition for event_base "
struct Event_base {... #ifndef _event_disable_thread_support/    * Threading Support */    /** the THREAD currently Running the event_loop for this base */    unsigned long th_owner_id;    /** A Lock to prevent conflicting accesses to this event_base */    /Lock void to prevent conflicting access to current event_base *th_base_lock    ;    /** the event whose callback is executing right now */    struct event *current_event;    /** A condition that gets signalled when we ' re do processing an     * event with waiters on it. */    void *current_ev Ent_cond;    /** number of threads blocking on current_event_cond. */    int current_event_waiters; #endif ...};

in the event.c
"Event_base's Lock enable "
struct event_base *event_base_new_with_config (const struct event_config *cfg) {... #ifndef _event_disable_thread_  Support//If the    evthread_locking_enabled () &&  //Test lock function is NULL, that is, if the libevent is initialized to support multi-threaded        (!cfg | |! ( Cfg->flags & Event_base_flag_nolock)) {//Determine if the current configuration supports lock        int r;        Application for recursive lock        Evthread_alloc_lock (Base->th_base_lock, evthread_locktype_recursive);        Base->defer_queue.lock = base->th_base_lock;        Application condition variable        evthread_alloc_cond (base->current_event_cond);        R = evthread_make_base_notifiable (base);        if (r<0) {            event_warnx ("%s:unable to make base notifiable.", __func__);            Event_base_free (base);            return NULL;        }    } #endif ...}

in the evthread-internal.h
" platform and multi-threaded correlation lock definition "
#ifndef WIN32  //non-Windows platform/* on Windows, the the-currently make DLLs, it's not allowed for us to * has shared g Lobal structures.  Thus, we only does the direct-call-to-function * code path if we know that the local shared library system supports it. * * #define EVTHREAD_EXPOSE_STRUCTS#ENDIF#IF! Defined (_event_disable_thread_support) && defined (evthread_expose_structs)//multi-threaded support + non-win platform ... #elif! Defined (_event_disable_thread_support)  //multi-threaded support +win platform ... #else/* _event_disable_thread_support *  //Multithreading not supported ... #endif
"event_base lock function "
 #if! defined (_event_disable_thread_support) && Defined (evthread_expose_structs)//multithreading support + non-win platform .../** acquire a lock. *///Get Lock # define EVLOCK_LOCK (Lockvar,mode) do {if (Lockvar) _evthread_lock_fns.lock (mode, Lockvar);} while (0)/** Rel Ease a lock */#define EVLOCK_UNLOCK (Lockvar,mode) do {if (Lockvar) _evthread_lock_fns.unlock (mode, Lockvar);  (0) .../** Lock an event_base, if it is the set up for locking. Acquires the lock in the base structure whose field is named ' Lockvar '.    *///Lock Event_base, if the event_base does support lock//get lock in base structure, the lock name is specified by Lockvar # define # Evbase_acquire_lock (base, Lockvar) do { Evlock_lock (base)->lockvar, 0);} while (0)/** Unlock a event_base, if it is set to locking. */#define EVBASE_RELEASE_LOCK (base, Lockvar) do {evlock_unlock (base)->lockvar, 0) and} while (0) ... #elif! Defined (_event_disable_thread_support)//multi-threaded support +win platform ... 


in thread.h

#if!defined (_event_disable_thread_support) | |  Defined (_event_in_doxygen) #define Evthread_lock_api_version 1/** @name Types of Locks lock type In fact, this contains the third type of lock, that is, 0 value represents  Normal lock @{*//** A recursive lock is one so can be acquired multiple times at once by the * same thread. No other process can allocate the lock until the thread that * have been holding it has unlocked it as many times as it Loc Ked it. *///a recursive lock type means that the lock can be obtained multiple times in the same thread, and the other thread cannot allocate the lock until//the thread holding the lock unlocks the same number of times # define evthread_locktype_recursive 1/* A read-write Lock is one, the allows multiple simultaneous readers, but the where any one writer excludes all other writers and readers. */#define EVTHREAD_LOCKTYPE_READWRITE 2/**@}*//** This structure describes the interface a threading library uses for * LO   Cking. It's used to tell Evthread_set_lock_callbacks () How to use * locking on this platform. *///Line lock operation function pointer struct//This structure is used to tell Evthread_set_lock_callbacks () How to use lock struct evthread_lock_callbacks on the current platform {     /** the CurreNT version of the locking API. Set this to    * evthread_lock_api_version */    int LOCK_API_VERSION;      /** which kinds of locks does this version of the locking api    * support? A Bitfield of Evthread_locktype_recursive and    * evthread_locktype_readwrite.     *    * (Note that RECURSIVE locks is currently mandatory, and     * READWRITE locks is not currently used.)     **/    unsigned supported_locktypes;    /** Function to allocate and initialize new lock of type ' LockType '.     * Returns NULL on failure. */    void * (*alloc) (unsigned locktype);     /** Function to release all Storage held in ' lock ', which is created    * with type ' LockType '. */    void (*free) (VoiD *lock, unsigned locktype);     /** acquire an already-allocated lock @ ' lock ' with mode ' mode '. &nbsp ;    * Returns 0 on success, and nonzero on failure. */    //holds the assigned lock pointed to by ' lock ' in ' mode ', 0 for success, nonzero for failure     int (*lock) (  unsigned mode, void *lock),     /** Release a lock at ' lock ' using mode ' mode '. Returns 0 on success,    * and nonzero on failure. */    int (*unlock) (unsigned mode, void *lock);};/ * * Sets a group of functions that Libevent should use for locking. * For full information on the required callback APIs, see the * documentation for the individual members of Evthread_lock_c Allbacks. * * Note that if you ' re using Windows or the Pthreads threading Library, you * probably shouldn ' t call this function; Instead, use * evthread_use_windows_threads () or evthread_use_posix_threads () if you can. */int evthread_set_lock_callbacks (const struct EVTHREAd_lock_callbacks *); #if (defined (WIN32) &&!defined (_event_disable_thread_support)) | |  Defined (_event_in_doxygen)/** sets up Libevent for use with Windows builtin locking and thread ID functions.    Unavailable if Libevent is not built for Windows. @return 0 on success,-1 on failure.           */int evthread_use_windows_threads (void); Lock enable on Windows/** Defined if Libevent is built with support for evthread_use_windows_threads () */#define Evthread_use_ windows_threads_implemented 1#endif#if defined (_event_have_pthreads) | |    Defined (_event_in_doxygen)/** sets up Libevent for use with Pthreads locking and thread ID functions.  Unavailable if Libevent is not a build for use with pthreads.    Requires libraries to link against Libevent_pthreads as well as Libevent. Enable libevent to use pthread locks and corresponding functions to get the thread ID if pthread is not supported when building libevent, it is not possible to use the function when using the request Link Libevent_pthreads Library and libevent Library @return 0 On success,-1 on failure.        */int evthread_use_pthreads (void);       Lock enable on Linux/** Defined if Libevent is built with supported for evthread_use_pthreads () */#define Evthread_use_pth  reads_implemented 1#endif/** Enable Debugging wrappers around the current lock callbacks. If Libevent * makes one of several common locking errors, exit with an assertion failure. * If you ' re going-to-call the This function, you must does so before any locks is * allocated. **/void evthread_enable_lock_debuging (void); #endif/* _event_disable_thread_support */

in the whatsnew-2.0.txt
2.8. evthread_* functions for Thread-safe structures.  Libevent structures can now is built with locking support.  This code makes it safe to add, remove, and activate events on a event base from a different thread. (Previously, if you wanted to write multithreaded code with Libevent, you could only a event_base or its events in one T  Hread at a time.)  If you want threading support and your ' re using pthreads, you can just call Evthread_use_pthreads ().  (You'll need to link against the Libevent_pthreads library in addition to Libevent_core.  These functions is not in Libevent_core.)  If you want threading support and your ' re using Windows, you can just call Evthread_use_windows_threads (). If you is using some locking system besides Windows and pthreads, you can enable the this on a per-event-base level by Writi ng functions to implement mutexes, conditions, and thread IDs, and passing them to evthread_set_lock_callbacks and Relat  Ed functions in Event2/thread.h. Once Locking FUnctions is enabled, every new event_base was created with a lock.   You can prevent a single event_base from being built with a lock disabled by using the Event_base_flag_nolock FLAG in its  Event_config.  If an event_base are created with a lock, it's safe to call Event_del, Event_add, and event_active on its events from any  Thread.  The event callbacks themselves is still all executed from the thread running the event loop.  A evbuffer or a Bufferevent object Threadsafe, call its *_enable_locking () function.  The HTTP API is not currently threadsafe. To build Libevent and threading support disabled, pass--disable-thread-support to the Configure script.



"Original" Libevent2 Lock related code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.