"Fossies" - the Fresh Open Source Software Archive

Member "apr-1.7.0/locks/win32/thread_mutex.c" (21 Mar 2019, 5798 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.h"
   18 #include "apr_private.h"
   19 #include "apr_general.h"
   20 #include "apr_strings.h"
   21 #include "apr_arch_thread_mutex.h"
   22 #include "apr_thread_mutex.h"
   23 #include "apr_portable.h"
   24 #include "apr_arch_misc.h"
   25 
   26 static apr_status_t thread_mutex_cleanup(void *data)
   27 {
   28     apr_thread_mutex_t *lock = data;
   29 
   30     if (lock->type == thread_mutex_critical_section) {
   31         lock->type = -1;
   32         DeleteCriticalSection(&lock->section);
   33     }
   34     else {
   35         if (!CloseHandle(lock->handle)) {
   36             return apr_get_os_error();
   37         }
   38     }
   39     return APR_SUCCESS;
   40 }
   41 
   42 APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
   43                                                   unsigned int flags,
   44                                                   apr_pool_t *pool)
   45 {
   46     (*mutex) = (apr_thread_mutex_t *)apr_palloc(pool, sizeof(**mutex));
   47 
   48     (*mutex)->pool = pool;
   49 
   50     if (flags & APR_THREAD_MUTEX_UNNESTED) {
   51         /* Use an auto-reset signaled event, ready to accept one
   52          * waiting thread.
   53          */
   54         (*mutex)->type = thread_mutex_unnested_event;
   55         (*mutex)->handle = CreateEvent(NULL, FALSE, TRUE, NULL);
   56     }
   57     else if (flags & APR_THREAD_MUTEX_TIMED) {
   58         (*mutex)->type = thread_mutex_nested_mutex;
   59         (*mutex)->handle = CreateMutex(NULL, FALSE, NULL);
   60     }
   61     else {
   62 #if APR_HAS_UNICODE_FS
   63         /* Critical Sections are terrific, performance-wise, on NT.
   64          * On Win9x, we cannot 'try' on a critical section, so we 
   65          * use a [slower] mutex object, instead.
   66          */
   67         IF_WIN_OS_IS_UNICODE {
   68             InitializeCriticalSection(&(*mutex)->section);
   69             (*mutex)->type = thread_mutex_critical_section;
   70             (*mutex)->handle = NULL;
   71         }
   72 #endif
   73 #if APR_HAS_ANSI_FS
   74         ELSE_WIN_OS_IS_ANSI {
   75             (*mutex)->type = thread_mutex_nested_mutex;
   76             (*mutex)->handle = CreateMutex(NULL, FALSE, NULL);
   77 
   78         }
   79 #endif
   80     }
   81 
   82     apr_pool_cleanup_register((*mutex)->pool, (*mutex), thread_mutex_cleanup,
   83                               apr_pool_cleanup_null);
   84     return APR_SUCCESS;
   85 }
   86 
   87 APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex)
   88 {
   89     if (mutex->type == thread_mutex_critical_section) {
   90         EnterCriticalSection(&mutex->section);
   91     }
   92     else {
   93         DWORD rv = WaitForSingleObject(mutex->handle, INFINITE);
   94         if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) {
   95             return (rv == WAIT_TIMEOUT) ? APR_EBUSY : apr_get_os_error();
   96         }
   97     }        
   98     return APR_SUCCESS;
   99 }
  100 
  101 APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex)
  102 {
  103     if (mutex->type == thread_mutex_critical_section) {
  104         if (!TryEnterCriticalSection(&mutex->section)) {
  105             return APR_EBUSY;
  106         }
  107     }
  108     else {
  109         DWORD rv = WaitForSingleObject(mutex->handle, 0);
  110         if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) {
  111             return (rv == WAIT_TIMEOUT) ? APR_EBUSY : apr_get_os_error();
  112         }
  113     }        
  114     return APR_SUCCESS;
  115 }
  116 
  117 APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
  118                                                  apr_interval_time_t timeout)
  119 {
  120     if (mutex->type != thread_mutex_critical_section) {
  121         DWORD rv, timeout_ms = 0;
  122         apr_interval_time_t t = timeout;
  123 
  124         do {
  125             if (t > 0) {
  126                 /* Given timeout is 64bit usecs whereas Windows timeouts are
  127                  * 32bit msecs and below INFINITE (2^32 - 1), so we may need
  128                  * multiple timed out waits...
  129                  */
  130                 if (t > apr_time_from_msec(INFINITE - 1)) {
  131                     timeout_ms = INFINITE - 1;
  132                     t -= apr_time_from_msec(INFINITE - 1);
  133                 }
  134                 else {
  135                     timeout_ms = (DWORD)apr_time_as_msec(t);
  136                     t = 0;
  137                 }
  138             }
  139             rv = WaitForSingleObject(mutex->handle, timeout_ms);
  140         } while (rv == WAIT_TIMEOUT && t > 0);
  141 
  142         if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) {
  143             return (rv == WAIT_TIMEOUT) ? APR_TIMEUP : apr_get_os_error();
  144         }
  145         return APR_SUCCESS;
  146     }        
  147 
  148     return APR_ENOTIMPL;
  149 }
  150 
  151 APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex)
  152 {
  153     if (mutex->type == thread_mutex_critical_section) {
  154         LeaveCriticalSection(&mutex->section);
  155     }
  156     else if (mutex->type == thread_mutex_unnested_event) {
  157         if (!SetEvent(mutex->handle)) {
  158             return apr_get_os_error();
  159         }
  160     }
  161     else if (mutex->type == thread_mutex_nested_mutex) {
  162         if (!ReleaseMutex(mutex->handle)) {
  163             return apr_get_os_error();
  164         }
  165     }
  166     return APR_SUCCESS;
  167 }
  168 
  169 APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex)
  170 {
  171     return apr_pool_cleanup_run(mutex->pool, mutex, thread_mutex_cleanup);
  172 }
  173 
  174 APR_POOL_IMPLEMENT_ACCESSOR(thread_mutex)
  175