"Fossies" - the Fresh Open Source Software Archive

Member "apr-1.7.0/locks/beos/thread_cond.c" (5 Mar 2016, 5403 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_cond.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 #include "apr_arch_thread_cond.h"
   19 #include "apr_strings.h"
   20 #include "apr_portable.h"
   21 
   22 static apr_status_t thread_cond_cleanup(void *data)
   23 {
   24     struct waiter *w;
   25     apr_thread_cond_t *cond = (apr_thread_cond_t *)data;
   26 
   27     acquire_sem(cond->lock);
   28     delete_sem(cond->lock);
   29 
   30     return APR_SUCCESS;
   31 }
   32 
   33 static struct waiter_t *make_waiter(apr_pool_t *pool)
   34 {
   35     struct waiter_t *w = (struct waiter_t*)
   36                        apr_palloc(pool, sizeof(struct waiter_t));
   37     if (w == NULL)
   38         return NULL;
   39       
   40     w->sem  = create_sem(0, "apr conditional waiter");
   41     if (w->sem < 0)
   42         return NULL;
   43 
   44     APR_RING_ELEM_INIT(w, link);
   45     
   46     return w;
   47 }
   48   
   49 APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
   50                                                  apr_pool_t *pool)
   51 {
   52     apr_thread_cond_t *new_cond;
   53     sem_id rv;
   54     int i;
   55 
   56     new_cond = (apr_thread_cond_t *)apr_palloc(pool, sizeof(apr_thread_cond_t));
   57 
   58     if (new_cond == NULL)
   59         return APR_ENOMEM;
   60 
   61     if ((rv = create_sem(1, "apr conditional lock")) < B_OK)
   62         return rv;
   63     
   64     new_cond->lock = rv;
   65     new_cond->pool = pool;
   66     APR_RING_INIT(&new_cond->alist, waiter_t, link);
   67     APR_RING_INIT(&new_cond->flist, waiter_t, link);
   68         
   69     for (i=0;i < 10 ;i++) {
   70         struct waiter_t *nw = make_waiter(pool);
   71         APR_RING_INSERT_TAIL(&new_cond->flist, nw, waiter_t, link);
   72     }
   73 
   74     apr_pool_cleanup_register(new_cond->pool,
   75                               (void *)new_cond, thread_cond_cleanup,
   76                               apr_pool_cleanup_null);
   77 
   78     *cond = new_cond;
   79     return APR_SUCCESS;
   80 }
   81 
   82 
   83 static apr_status_t do_wait(apr_thread_cond_t *cond, apr_thread_mutex_t *mutex,
   84                             apr_interval_time_t timeout)
   85 {
   86     struct waiter_t *wait;
   87     thread_id cth = find_thread(NULL);
   88     apr_status_t rv;
   89     int flags = B_RELATIVE_TIMEOUT;
   90     
   91     /* We must be the owner of the mutex or we can't do this... */    
   92     if (mutex->owner != cth) {
   93         /* What should we return??? */
   94         return APR_EINVAL;
   95     }
   96 
   97     acquire_sem(cond->lock);
   98     wait = APR_RING_FIRST(&cond->flist);
   99     if (wait)
  100         APR_RING_REMOVE(wait, link);
  101     else
  102         wait = make_waiter(cond->pool);   
  103     APR_RING_INSERT_TAIL(&cond->alist, wait, waiter_t, link);
  104     cond->condlock = mutex;
  105     release_sem(cond->lock);
  106        
  107     apr_thread_mutex_unlock(cond->condlock);
  108 
  109     if (timeout == 0)
  110         flags = 0;
  111         
  112     rv = acquire_sem_etc(wait->sem, 1, flags, timeout);
  113 
  114     apr_thread_mutex_lock(cond->condlock);
  115     
  116     if (rv != B_OK) {
  117         if (rv == B_TIMED_OUT)
  118             return APR_TIMEUP;
  119         return rv;       
  120     }
  121 
  122     acquire_sem(cond->lock);
  123     APR_RING_REMOVE(wait, link);
  124     APR_RING_INSERT_TAIL(&cond->flist, wait, waiter_t, link);
  125     release_sem(cond->lock);
  126     
  127     return APR_SUCCESS;
  128 }
  129 
  130 APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
  131                                                apr_thread_mutex_t *mutex)
  132 {
  133     return do_wait(cond, mutex, 0);
  134 }
  135 
  136 APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
  137                                                     apr_thread_mutex_t *mutex,
  138                                                     apr_interval_time_t timeout)
  139 {
  140     return do_wait(cond, mutex, timeout);
  141 }
  142 
  143 APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
  144 {
  145     struct waiter_t *wake;
  146 
  147     acquire_sem(cond->lock);    
  148     if (!APR_RING_EMPTY(&cond->alist, waiter_t, link)) {
  149         wake = APR_RING_FIRST(&cond->alist);
  150         APR_RING_REMOVE(wake, link);
  151         release_sem(wake->sem);
  152         APR_RING_INSERT_TAIL(&cond->flist, wake, waiter_t, link);
  153     }
  154     release_sem(cond->lock);
  155     
  156     return APR_SUCCESS;
  157 }
  158 
  159 APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
  160 {
  161     struct waiter_t *wake;
  162     
  163     acquire_sem(cond->lock);
  164     while (! APR_RING_EMPTY(&cond->alist, waiter_t, link)) {
  165         wake = APR_RING_FIRST(&cond->alist);
  166         APR_RING_REMOVE(wake, link);
  167         release_sem(wake->sem);
  168         APR_RING_INSERT_TAIL(&cond->flist, wake, waiter_t, link);
  169     }
  170     release_sem(cond->lock);
  171     
  172     return APR_SUCCESS;
  173 }
  174 
  175 APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond)
  176 {
  177     apr_status_t stat;
  178     if ((stat = thread_cond_cleanup(cond)) == APR_SUCCESS) {
  179         apr_pool_cleanup_kill(cond->pool, cond, thread_cond_cleanup);
  180         return APR_SUCCESS;
  181     }
  182     return stat;
  183 }
  184 
  185 APR_POOL_IMPLEMENT_ACCESSOR(thread_cond)
  186