diff options
Diffstat (limited to 'servers/lloadd/libevent_support.c')
-rw-r--r-- | servers/lloadd/libevent_support.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/servers/lloadd/libevent_support.c b/servers/lloadd/libevent_support.c new file mode 100644 index 0000000..2f94c5e --- /dev/null +++ b/servers/lloadd/libevent_support.c @@ -0,0 +1,171 @@ +/* libevent_support.c - routines to bridge libldap and libevent */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 2017-2022 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * <http://www.OpenLDAP.org/license.html>. + */ + +#include "portable.h" + +#include <ac/time.h> + +#include <event2/event.h> +#include <event2/thread.h> + +#include "lload.h" +#include "ldap_pvt_thread.h" + +static void * +lload_libevent_mutex_init( unsigned locktype ) +{ + int rc; + ldap_pvt_thread_mutex_t *mutex = + ch_malloc( sizeof(ldap_pvt_thread_mutex_t) ); + + if ( locktype & EVTHREAD_LOCKTYPE_RECURSIVE ) { + rc = ldap_pvt_thread_mutex_recursive_init( mutex ); + } else { + rc = ldap_pvt_thread_mutex_init( mutex ); + } + if ( rc ) { + ch_free( mutex ); + mutex = NULL; + } + return mutex; +} + +static void +lload_libevent_mutex_destroy( void *lock, unsigned locktype ) +{ + int rc; + ldap_pvt_thread_mutex_t *mutex = lock; + + rc = ldap_pvt_thread_mutex_destroy( mutex ); + assert( rc == 0 ); + ch_free( mutex ); +} + +static int +lload_libevent_mutex_lock( unsigned mode, void *lock ) +{ + ldap_pvt_thread_mutex_t *mutex = lock; + + if ( mode & EVTHREAD_TRY ) { + return ldap_pvt_thread_mutex_trylock( mutex ); + } else { + return ldap_pvt_thread_mutex_lock( mutex ); + } +} + +static int +lload_libevent_mutex_unlock( unsigned mode, void *lock ) +{ + ldap_pvt_thread_mutex_t *mutex = lock; + + return ldap_pvt_thread_mutex_unlock( mutex ); +} + +static void * +lload_libevent_cond_init( unsigned condtype ) +{ + int rc; + ldap_pvt_thread_cond_t *cond = + ch_malloc( sizeof(ldap_pvt_thread_cond_t) ); + + assert( condtype == 0 ); + rc = ldap_pvt_thread_cond_init( cond ); + if ( rc ) { + ch_free( cond ); + cond = NULL; + } + return cond; +} + +static void +lload_libevent_cond_destroy( void *c ) +{ + int rc; + ldap_pvt_thread_cond_t *cond = c; + + rc = ldap_pvt_thread_cond_destroy( cond ); + assert( rc == 0 ); + ch_free( c ); +} + +static int +lload_libevent_cond_signal( void *c, int broadcast ) +{ + ldap_pvt_thread_cond_t *cond = c; + + if ( broadcast ) { + return ldap_pvt_thread_cond_broadcast( cond ); + } else { + return ldap_pvt_thread_cond_signal( cond ); + } +} + +static int +lload_libevent_cond_timedwait( + void *c, + void *lock, + const struct timeval *timeout ) +{ + ldap_pvt_thread_cond_t *cond = c; + ldap_pvt_thread_mutex_t *mutex = lock; + + /* + * libevent does not seem to request a timeout, this is true as of 2.1.8 + * that has just been marked the first stable release of the 2.1 series + */ + assert( timeout == NULL ); + + return ldap_pvt_thread_cond_wait( cond, mutex ); +} + +int +lload_libevent_init( void ) +{ + struct evthread_lock_callbacks cbs = { + EVTHREAD_LOCK_API_VERSION, + EVTHREAD_LOCKTYPE_RECURSIVE, + lload_libevent_mutex_init, + lload_libevent_mutex_destroy, + lload_libevent_mutex_lock, + lload_libevent_mutex_unlock + }; + struct evthread_condition_callbacks cond_cbs = { + EVTHREAD_CONDITION_API_VERSION, + lload_libevent_cond_init, + lload_libevent_cond_destroy, + lload_libevent_cond_signal, + lload_libevent_cond_timedwait + }; + +#ifndef BALANCER_MODULE + /* only necessary if lload is a server, slapd already calls + * ldap_pvt_thread_initialize() */ + if ( ldap_pvt_thread_initialize() ) { + return -1; + } +#endif + + evthread_set_lock_callbacks( &cbs ); + evthread_set_condition_callbacks( &cond_cbs ); + evthread_set_id_callback( ldap_pvt_thread_self ); + return 0; +} + +void +lload_libevent_destroy( void ) +{ + libevent_global_shutdown(); +} |