"Fossies" - the Fresh Open Source Software Archive

Member "apr-1.7.0/locks/beos/thread_mutex.c" (7 Apr 2017, 5873 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 /*Read/Write locking implementation based on the MultiLock code from
   18  * Stephen Beaulieu <hippo@be.com>
   19  */
   20  
   21 #include "apr_arch_thread_mutex.h"
   22 #include "apr_strings.h"
   23 #include "apr_portable.h"
   24 
   25 static apr_status_t _thread_mutex_cleanup(void * data)
   26 {
   27     apr_thread_mutex_t *lock = (apr_thread_mutex_t*)data;
   28     if (lock->LockCount != 0) {
   29         /* we're still locked... */
   30         while (atomic_add(&lock->LockCount , -1) > 1){
   31             /* OK we had more than one person waiting on the lock so 
   32              * the sem is also locked. Release it until we have no more
   33              * locks left.
   34              */
   35             release_sem (lock->Lock);
   36         }
   37     }
   38     delete_sem(lock->Lock);
   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     apr_thread_mutex_t *new_m;
   47     apr_status_t stat = APR_SUCCESS;
   48   
   49     new_m = (apr_thread_mutex_t *)apr_pcalloc(pool, sizeof(apr_thread_mutex_t));
   50     if (new_m == NULL){
   51         return APR_ENOMEM;
   52     }
   53     
   54     if ((stat = create_sem(0, "APR_Lock")) < B_NO_ERROR) {
   55         _thread_mutex_cleanup(new_m);
   56         return stat;
   57     }
   58     new_m->LockCount = 0;
   59     new_m->Lock = stat;  
   60     new_m->pool  = pool;
   61 
   62     /* Optimal default is APR_THREAD_MUTEX_UNNESTED, 
   63      * no additional checks required for either flag.
   64      */
   65     new_m->nested = flags & APR_THREAD_MUTEX_NESTED;
   66 
   67     apr_pool_cleanup_register(new_m->pool, (void *)new_m, _thread_mutex_cleanup,
   68                               apr_pool_cleanup_null);
   69 
   70     (*mutex) = new_m;
   71     return APR_SUCCESS;
   72 }
   73 
   74 #if APR_HAS_CREATE_LOCKS_NP
   75 APR_DECLARE(apr_status_t) apr_thread_mutex_create_np(apr_thread_mutex_t **mutex,
   76                                                    const char *fname,
   77                                                    apr_lockmech_e_np mech,
   78                                                    apr_pool_t *pool)
   79 {
   80     return APR_ENOTIMPL;
   81 }       
   82 #endif
   83   
   84 APR_DECLARE(apr_status_t) apr_thread_mutex_lock(apr_thread_mutex_t *mutex)
   85 {
   86     int32 stat;
   87     thread_id me = find_thread(NULL);
   88     
   89     if (mutex->nested && mutex->owner == me) {
   90         mutex->owner_ref++;
   91         return APR_SUCCESS;
   92     }
   93     
   94     if (atomic_add(&mutex->LockCount, 1) > 0) {
   95         if ((stat = acquire_sem(mutex->Lock)) < B_NO_ERROR) {
   96             /* Oh dear, acquire_sem failed!!  */
   97             atomic_add(&mutex->LockCount, -1);
   98             return stat;
   99         }
  100     }
  101 
  102     mutex->owner = me;
  103     mutex->owner_ref = 1;
  104     
  105     return APR_SUCCESS;
  106 }
  107 
  108 APR_DECLARE(apr_status_t) apr_thread_mutex_trylock(apr_thread_mutex_t *mutex)
  109 {
  110     int32 stat;
  111     thread_id me = find_thread(NULL);
  112     
  113     if (mutex->nested && mutex->owner == me) {
  114         mutex->owner_ref++;
  115         return APR_SUCCESS;
  116     }
  117     
  118     if (atomic_add(&mutex->LockCount, 1) > 0) {
  119         if ((stat = acquire_sem_etc(mutex->Lock, 1, 0, 0)) < B_NO_ERROR) {
  120             atomic_add(&mutex->LockCount, -1);
  121             if (stat == B_WOULD_BLOCK) {
  122                 stat = APR_EBUSY;
  123             }
  124             return stat;
  125         }
  126     }
  127 
  128     mutex->owner = me;
  129     mutex->owner_ref = 1;
  130     
  131     return APR_SUCCESS;
  132 }
  133 
  134 APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
  135                                                  apr_interval_time_t timeout)
  136 {
  137     int32 stat;
  138     thread_id me = find_thread(NULL);
  139     
  140     if (mutex->nested && mutex->owner == me) {
  141         mutex->owner_ref++;
  142         return APR_SUCCESS;
  143     }
  144     
  145     if (atomic_add(&mutex->LockCount, 1) > 0) {
  146         if (timeout <= 0) {
  147             stat = B_TIMED_OUT;
  148         }
  149         else {
  150             stat = acquire_sem_etc(mutex->Lock, 1, B_RELATIVE_TIMEOUT,
  151                                    timeout);
  152         }
  153         if (stat < B_NO_ERROR) {
  154             atomic_add(&mutex->LockCount, -1);
  155             if (stat == B_TIMED_OUT) {
  156                 stat = APR_TIMEUP;
  157             }
  158             return stat;
  159         }
  160     }
  161 
  162     mutex->owner = me;
  163     mutex->owner_ref = 1;
  164     
  165     return APR_SUCCESS;
  166 }
  167 
  168 APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex)
  169 {
  170     int32 stat;
  171         
  172     if (mutex->nested && mutex->owner == find_thread(NULL)) {
  173         mutex->owner_ref--;
  174         if (mutex->owner_ref > 0)
  175             return APR_SUCCESS;
  176     }
  177     
  178     if (atomic_add(&mutex->LockCount, -1) > 1) {
  179         if ((stat = release_sem(mutex->Lock)) < B_NO_ERROR) {
  180             atomic_add(&mutex->LockCount, 1);
  181             return stat;
  182         }
  183     }
  184 
  185     mutex->owner = -1;
  186     mutex->owner_ref = 0;
  187 
  188     return APR_SUCCESS;
  189 }
  190 
  191 APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex)
  192 {
  193     apr_status_t stat;
  194     if ((stat = _thread_mutex_cleanup(mutex)) == APR_SUCCESS) {
  195         apr_pool_cleanup_kill(mutex->pool, mutex, _thread_mutex_cleanup);
  196         return APR_SUCCESS;
  197     }
  198     return stat;
  199 }
  200 
  201 APR_POOL_IMPLEMENT_ACCESSOR(thread_mutex)
  202