"Fossies" - the Fresh Open Source Software Archive

Member "apr-1.7.0/locks/unix/thread_mutex.c" (21 Mar 2019, 7859 Bytes) of package /linux/www/apr-1.7.0.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "thread_mutex.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.6.5_vs_1.7.0.

    1 /* Licensed to the Apache Software Foundation (ASF) under one or more
    2  * contributor license agreements.  See the NOTICE file distributed with
    3  * this work for additional information regarding copyright ownership.
    4  * The ASF licenses this file to You under the Apache License, Version 2.0
    5  * (the "License"); you may not use this file except in compliance with
    6  * the License.  You may obtain a copy of the License at
    7  *
    8  *     http://www.apache.org/licenses/LICENSE-2.0
    9  *
   10  * Unless required by applicable law or agreed to in writing, software
   11  * distributed under the License is distributed on an "AS IS" BASIS,
   12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13  * See the License for the specific language governing permissions and
   14  * limitations under the License.
   15  */
   16 
   17 #include "apr_arch_thread_mutex.h"
   18 #define APR_WANT_MEMFUNC
   19 #include "apr_want.h"
   20 
   21 #if APR_HAS_THREADS
   22 
   23 static apr_status_t thread_mutex_cleanup(void *data)
   24 {
   25     apr_thread_mutex_t *mutex = data;
   26     apr_status_t rv;
   27 
   28     rv = pthread_mutex_destroy(&mutex->mutex);
   29 #ifdef HAVE_ZOS_PTHREADS
   30     if (rv) {
   31         rv = errno;
   32     }
   33 #endif
   34     return rv;
   35 } 
   36 
   37 APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
   38                                                   unsigned int flags,
   39                                                   apr_pool_t *pool)
   40 {
   41     apr_thread_mutex_t *new_mutex;
   42     apr_status_t rv;
   43     
   44 #ifndef HAVE_PTHREAD_MUTEX_RECURSIVE
   45     if (flags & APR_THREAD_MUTEX_NESTED) {
   46         return APR_ENOTIMPL;
   47     }
   48 #endif
   49 
   50     new_mutex = apr_pcalloc(pool, sizeof(apr_thread_mutex_t));
   51     new_mutex->pool = pool;
   52 
   53 #ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
   54     if (flags & APR_THREAD_MUTEX_NESTED) {
   55         pthread_mutexattr_t mattr;
   56         
   57         rv = pthread_mutexattr_init(&mattr);
   58         if (rv) return rv;
   59         
   60         rv = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
   61         if (rv) {
   62             pthread_mutexattr_destroy(&mattr);
   63             return rv;
   64         }
   65          
   66         rv = pthread_mutex_init(&new_mutex->mutex, &mattr);
   67         
   68         pthread_mutexattr_destroy(&mattr);
   69     } else
   70 #endif
   71         rv = pthread_mutex_init(&new_mutex->mutex, NULL);
   72 
   73     if (rv) {
   74 #ifdef HAVE_ZOS_PTHREADS
   75         rv = errno;
   76 #endif
   77         return rv;
   78     }
   79 
   80 #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
   81     if (flags & APR_THREAD_MUTEX_TIMED) {
   82         rv = apr_thread_cond_create(&new_mutex->cond, pool);
   83         if (rv) {
   84 #ifdef HAVE_ZOS_PTHREADS
   85             rv = errno;
   86 #endif
   87             pthread_mutex_destroy(&new_mutex->mutex);
   88             return rv;
   89         }
   90     }
   91 #endif
   92 
   93     apr_pool_cleanup_register(new_mutex->pool,
   94                               new_mutex, thread_mutex_cleanup,
   95                               apr_pool_cleanup_null);
   96 
   97     *mutex = new_mutex;
   98     return APR_SUCCESS;
   99 }
  100 
  101 APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex)
  102 {
  103     apr_status_t rv;
  104 
  105     if (mutex->cond) {
  106         apr_status_t rv2;
  107 
  108         rv = pthread_mutex_lock(&mutex->mutex);
  109         if (rv) {
  110 #ifdef HAVE_ZOS_PTHREADS
  111             rv = errno;
  112 #endif
  113             return rv;
  114         }
  115 
  116         if (mutex->locked) {
  117             mutex->num_waiters++;
  118             rv = apr_thread_cond_wait(mutex->cond, mutex);
  119             mutex->num_waiters--;
  120         }
  121         else {
  122             mutex->locked = 1;
  123         }
  124 
  125         rv2 = pthread_mutex_unlock(&mutex->mutex);
  126         if (rv2 && !rv) {
  127 #ifdef HAVE_ZOS_PTHREADS
  128             rv = errno;
  129 #else
  130             rv = rv2;
  131 #endif
  132         }
  133 
  134         return rv;
  135     }
  136 
  137     rv = pthread_mutex_lock(&mutex->mutex);
  138 #ifdef HAVE_ZOS_PTHREADS
  139     if (rv) {
  140         rv = errno;
  141     }
  142 #endif
  143 
  144     return rv;
  145 }
  146 
  147 APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex)
  148 {
  149     apr_status_t rv;
  150 
  151     if (mutex->cond) {
  152         apr_status_t rv2;
  153 
  154         rv = pthread_mutex_lock(&mutex->mutex);
  155         if (rv) {
  156 #ifdef HAVE_ZOS_PTHREADS
  157             rv = errno;
  158 #endif
  159             return rv;
  160         }
  161 
  162         if (mutex->locked) {
  163             rv = APR_EBUSY;
  164         }
  165         else {
  166             mutex->locked = 1;
  167         }
  168 
  169         rv2 = pthread_mutex_unlock(&mutex->mutex);
  170         if (rv2) {
  171 #ifdef HAVE_ZOS_PTHREADS
  172             rv = errno;
  173 #else
  174             rv = rv2;
  175 #endif
  176         }
  177 
  178         return rv;
  179     }
  180 
  181     rv = pthread_mutex_trylock(&mutex->mutex);
  182     if (rv) {
  183 #ifdef HAVE_ZOS_PTHREADS
  184         rv = errno;
  185 #endif
  186         return (rv == EBUSY) ? APR_EBUSY : rv;
  187     }
  188 
  189     return APR_SUCCESS;
  190 }
  191 
  192 APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
  193                                                  apr_interval_time_t timeout)
  194 {
  195     apr_status_t rv = APR_ENOTIMPL;
  196 #if APR_HAS_TIMEDLOCKS
  197 
  198 #ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK
  199     if (timeout <= 0) {
  200         rv = pthread_mutex_trylock(&mutex->mutex);
  201         if (rv) {
  202 #ifdef HAVE_ZOS_PTHREADS
  203             rv = errno;
  204 #endif
  205             if (rv == EBUSY) {
  206                 rv = APR_TIMEUP;
  207             }
  208         }
  209     }
  210     else {
  211         struct timespec abstime;
  212 
  213         timeout += apr_time_now();
  214         abstime.tv_sec = apr_time_sec(timeout);
  215         abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */
  216 
  217         rv = pthread_mutex_timedlock(&mutex->mutex, &abstime);
  218         if (rv) {
  219 #ifdef HAVE_ZOS_PTHREADS
  220             rv = errno;
  221 #endif
  222             if (rv == ETIMEDOUT) {
  223                 rv = APR_TIMEUP;
  224             }
  225         }
  226     }
  227 
  228 #else /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
  229 
  230     if (mutex->cond) {
  231         rv = pthread_mutex_lock(&mutex->mutex);
  232         if (rv) {
  233 #ifdef HAVE_ZOS_PTHREADS
  234             rv = errno;
  235 #endif
  236             return rv;
  237         }
  238 
  239         if (mutex->locked) {
  240             if (timeout <= 0) {
  241                 rv = APR_TIMEUP;
  242             }
  243             else {
  244                 mutex->num_waiters++;
  245                 do {
  246                     rv = apr_thread_cond_timedwait(mutex->cond, mutex,
  247                                                    timeout);
  248                     if (rv) {
  249 #ifdef HAVE_ZOS_PTHREADS
  250                         rv = errno;
  251 #endif
  252                         break;
  253                     }
  254                 } while (mutex->locked);
  255                 mutex->num_waiters--;
  256             }
  257             if (rv) {
  258                 pthread_mutex_unlock(&mutex->mutex);
  259                 return rv;
  260             }
  261         }
  262 
  263         mutex->locked = 1;
  264 
  265         rv = pthread_mutex_unlock(&mutex->mutex);
  266         if (rv) {
  267 #ifdef HAVE_ZOS_PTHREADS
  268             rv = errno;
  269 #endif
  270             return rv;
  271         }
  272     }
  273 
  274 #endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
  275 
  276 #endif /* APR_HAS_TIMEDLOCKS */
  277     return rv;
  278 }
  279 
  280 APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex)
  281 {
  282     apr_status_t status;
  283 
  284     if (mutex->cond) {
  285         status = pthread_mutex_lock(&mutex->mutex);
  286         if (status) {
  287 #ifdef HAVE_ZOS_PTHREADS
  288             status = errno;
  289 #endif
  290             return status;
  291         }
  292 
  293         if (!mutex->locked) {
  294             status = APR_EINVAL;
  295         }
  296         else if (mutex->num_waiters) {
  297             status = apr_thread_cond_signal(mutex->cond);
  298         }
  299         if (status) {
  300             pthread_mutex_unlock(&mutex->mutex);
  301             return status;
  302         }
  303 
  304         mutex->locked = 0;
  305     }
  306 
  307     status = pthread_mutex_unlock(&mutex->mutex);
  308 #ifdef HAVE_ZOS_PTHREADS
  309     if (status) {
  310         status = errno;
  311     }
  312 #endif
  313 
  314     return status;
  315 }
  316 
  317 APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex)
  318 {
  319     apr_status_t rv, rv2 = APR_SUCCESS;
  320 
  321     if (mutex->cond) {
  322         rv2 = apr_thread_cond_destroy(mutex->cond);
  323     }
  324     rv = apr_pool_cleanup_run(mutex->pool, mutex, thread_mutex_cleanup);
  325     if (rv == APR_SUCCESS) {
  326         rv = rv2;
  327     }
  328     
  329     return rv;
  330 }
  331 
  332 APR_POOL_IMPLEMENT_ACCESSOR(thread_mutex)
  333 
  334 #endif /* APR_HAS_THREADS */