1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 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();
}
|