1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/evthread_pthread.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,189 @@ 1.4 +/* 1.5 + * Copyright 2009-2012 Niels Provos and Nick Mathewson 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1. Redistributions of source code must retain the above copyright 1.11 + * notice, this list of conditions and the following disclaimer. 1.12 + * 2. Redistributions in binary form must reproduce the above copyright 1.13 + * notice, this list of conditions and the following disclaimer in the 1.14 + * documentation and/or other materials provided with the distribution. 1.15 + * 3. The name of the author may not be used to endorse or promote products 1.16 + * derived from this software without specific prior written permission. 1.17 + * 1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.28 + */ 1.29 +#include "event2/event-config.h" 1.30 + 1.31 +/* With glibc we need to define this to get PTHREAD_MUTEX_RECURSIVE. */ 1.32 +#define _GNU_SOURCE 1.33 +#include <pthread.h> 1.34 + 1.35 +struct event_base; 1.36 +#include "event2/thread.h" 1.37 + 1.38 +#include <stdlib.h> 1.39 +#include <string.h> 1.40 +#include "mm-internal.h" 1.41 +#include "evthread-internal.h" 1.42 + 1.43 +static pthread_mutexattr_t attr_recursive; 1.44 + 1.45 +static void * 1.46 +evthread_posix_lock_alloc(unsigned locktype) 1.47 +{ 1.48 + pthread_mutexattr_t *attr = NULL; 1.49 + pthread_mutex_t *lock = mm_malloc(sizeof(pthread_mutex_t)); 1.50 + if (!lock) 1.51 + return NULL; 1.52 + if (locktype & EVTHREAD_LOCKTYPE_RECURSIVE) 1.53 + attr = &attr_recursive; 1.54 + if (pthread_mutex_init(lock, attr)) { 1.55 + mm_free(lock); 1.56 + return NULL; 1.57 + } 1.58 + return lock; 1.59 +} 1.60 + 1.61 +static void 1.62 +evthread_posix_lock_free(void *_lock, unsigned locktype) 1.63 +{ 1.64 + pthread_mutex_t *lock = _lock; 1.65 + pthread_mutex_destroy(lock); 1.66 + mm_free(lock); 1.67 +} 1.68 + 1.69 +static int 1.70 +evthread_posix_lock(unsigned mode, void *_lock) 1.71 +{ 1.72 + pthread_mutex_t *lock = _lock; 1.73 + if (mode & EVTHREAD_TRY) 1.74 + return pthread_mutex_trylock(lock); 1.75 + else 1.76 + return pthread_mutex_lock(lock); 1.77 +} 1.78 + 1.79 +static int 1.80 +evthread_posix_unlock(unsigned mode, void *_lock) 1.81 +{ 1.82 + pthread_mutex_t *lock = _lock; 1.83 + return pthread_mutex_unlock(lock); 1.84 +} 1.85 + 1.86 +static unsigned long 1.87 +evthread_posix_get_id(void) 1.88 +{ 1.89 + union { 1.90 + pthread_t thr; 1.91 +#if _EVENT_SIZEOF_PTHREAD_T > _EVENT_SIZEOF_LONG 1.92 + ev_uint64_t id; 1.93 +#else 1.94 + unsigned long id; 1.95 +#endif 1.96 + } r; 1.97 +#if _EVENT_SIZEOF_PTHREAD_T < _EVENT_SIZEOF_LONG 1.98 + memset(&r, 0, sizeof(r)); 1.99 +#endif 1.100 + r.thr = pthread_self(); 1.101 + return (unsigned long)r.id; 1.102 +} 1.103 + 1.104 +static void * 1.105 +evthread_posix_cond_alloc(unsigned condflags) 1.106 +{ 1.107 + pthread_cond_t *cond = mm_malloc(sizeof(pthread_cond_t)); 1.108 + if (!cond) 1.109 + return NULL; 1.110 + if (pthread_cond_init(cond, NULL)) { 1.111 + mm_free(cond); 1.112 + return NULL; 1.113 + } 1.114 + return cond; 1.115 +} 1.116 + 1.117 +static void 1.118 +evthread_posix_cond_free(void *_cond) 1.119 +{ 1.120 + pthread_cond_t *cond = _cond; 1.121 + pthread_cond_destroy(cond); 1.122 + mm_free(cond); 1.123 +} 1.124 + 1.125 +static int 1.126 +evthread_posix_cond_signal(void *_cond, int broadcast) 1.127 +{ 1.128 + pthread_cond_t *cond = _cond; 1.129 + int r; 1.130 + if (broadcast) 1.131 + r = pthread_cond_broadcast(cond); 1.132 + else 1.133 + r = pthread_cond_signal(cond); 1.134 + return r ? -1 : 0; 1.135 +} 1.136 + 1.137 +static int 1.138 +evthread_posix_cond_wait(void *_cond, void *_lock, const struct timeval *tv) 1.139 +{ 1.140 + int r; 1.141 + pthread_cond_t *cond = _cond; 1.142 + pthread_mutex_t *lock = _lock; 1.143 + 1.144 + if (tv) { 1.145 + struct timeval now, abstime; 1.146 + struct timespec ts; 1.147 + evutil_gettimeofday(&now, NULL); 1.148 + evutil_timeradd(&now, tv, &abstime); 1.149 + ts.tv_sec = abstime.tv_sec; 1.150 + ts.tv_nsec = abstime.tv_usec*1000; 1.151 + r = pthread_cond_timedwait(cond, lock, &ts); 1.152 + if (r == ETIMEDOUT) 1.153 + return 1; 1.154 + else if (r) 1.155 + return -1; 1.156 + else 1.157 + return 0; 1.158 + } else { 1.159 + r = pthread_cond_wait(cond, lock); 1.160 + return r ? -1 : 0; 1.161 + } 1.162 +} 1.163 + 1.164 +int 1.165 +evthread_use_pthreads(void) 1.166 +{ 1.167 + struct evthread_lock_callbacks cbs = { 1.168 + EVTHREAD_LOCK_API_VERSION, 1.169 + EVTHREAD_LOCKTYPE_RECURSIVE, 1.170 + evthread_posix_lock_alloc, 1.171 + evthread_posix_lock_free, 1.172 + evthread_posix_lock, 1.173 + evthread_posix_unlock 1.174 + }; 1.175 + struct evthread_condition_callbacks cond_cbs = { 1.176 + EVTHREAD_CONDITION_API_VERSION, 1.177 + evthread_posix_cond_alloc, 1.178 + evthread_posix_cond_free, 1.179 + evthread_posix_cond_signal, 1.180 + evthread_posix_cond_wait 1.181 + }; 1.182 + /* Set ourselves up to get recursive locks. */ 1.183 + if (pthread_mutexattr_init(&attr_recursive)) 1.184 + return -1; 1.185 + if (pthread_mutexattr_settype(&attr_recursive, PTHREAD_MUTEX_RECURSIVE)) 1.186 + return -1; 1.187 + 1.188 + evthread_set_lock_callbacks(&cbs); 1.189 + evthread_set_condition_callbacks(&cond_cbs); 1.190 + evthread_set_id_callback(evthread_posix_get_id); 1.191 + return 0; 1.192 +}