"Fossies" - the Fresh Open Source Software Archive

Member "apr-1.7.0/locks/os2/thread_cond.c" (5 Mar 2016, 4975 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_general.h"
   18 #include "apr_lib.h"
   19 #include "apr_strings.h"
   20 #include "apr_portable.h"
   21 #include "apr_arch_thread_mutex.h"
   22 #include "apr_arch_thread_cond.h"
   23 #include "apr_arch_file_io.h"
   24 #include <string.h>
   25 
   26 #ifndef DCE_POSTONE
   27 #define DCE_POSTONE   0x0800 // Post one flag
   28 #endif
   29 
   30 static apr_status_t thread_cond_cleanup(void *data)
   31 {
   32     apr_thread_cond_t *cv = data;
   33 
   34     if (cv->semaphore) {
   35         DosCloseEventSem(cv->semaphore);
   36     }
   37 
   38     if (cv->mutex) {
   39         DosCloseMutexSem(cv->mutex);
   40     }
   41 
   42     return APR_SUCCESS;
   43 }
   44 
   45 
   46 
   47 APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
   48                                                  apr_pool_t *pool)
   49 {
   50     int rc;
   51     apr_thread_cond_t *cv;
   52 
   53     cv = apr_pcalloc(pool, sizeof(**cond));
   54     rc = DosCreateEventSem(NULL, &cv->semaphore, DCE_POSTONE, FALSE);
   55 
   56     if (rc == 0) {
   57         rc = DosCreateMutexSem(NULL, &cv->mutex, 0, FALSE);
   58     }
   59 
   60     *cond = cv;
   61     cv->pool = pool;
   62     apr_pool_cleanup_register(cv->pool, cv, thread_cond_cleanup,
   63                               apr_pool_cleanup_null);
   64 
   65     return APR_FROM_OS_ERROR(rc);
   66 }
   67 
   68 
   69 
   70 static apr_status_t thread_cond_timedwait(apr_thread_cond_t *cond,
   71                                           apr_thread_mutex_t *mutex,
   72                                           ULONG timeout_ms )
   73 {
   74     ULONG rc;
   75     apr_status_t rv = APR_SUCCESS;
   76     int wake = FALSE;
   77     unsigned long generation;
   78 
   79     DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
   80     cond->num_waiting++;
   81     generation = cond->generation;
   82     DosReleaseMutexSem(cond->mutex);
   83 
   84     apr_thread_mutex_unlock(mutex);
   85 
   86     do {
   87         rc = DosWaitEventSem(cond->semaphore, timeout_ms);
   88 
   89         DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
   90 
   91         if (cond->num_wake) {
   92             if (cond->generation != generation) {
   93                 cond->num_wake--;
   94                 cond->num_waiting--;
   95                 rv = APR_SUCCESS;
   96                 break;
   97             } else {
   98                 wake = TRUE;
   99             }
  100         }
  101         else if (rc != 0) {
  102             cond->num_waiting--;
  103             rv = APR_TIMEUP;
  104             break;
  105         }
  106 
  107         DosReleaseMutexSem(cond->mutex);
  108 
  109         if (wake) {
  110             wake = FALSE;
  111             DosPostEventSem(cond->semaphore);
  112         }
  113     } while (1);
  114 
  115     DosReleaseMutexSem(cond->mutex);
  116     apr_thread_mutex_lock(mutex);
  117     return rv;
  118 }
  119 
  120 
  121 
  122 APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
  123                                                apr_thread_mutex_t *mutex)
  124 {
  125     return thread_cond_timedwait(cond, mutex, SEM_INDEFINITE_WAIT);
  126 }
  127 
  128 
  129 
  130 APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
  131                                                     apr_thread_mutex_t *mutex,
  132                                                     apr_interval_time_t timeout)
  133 {
  134     ULONG timeout_ms = (timeout >= 0) ? apr_time_as_msec(timeout)
  135                                       : SEM_INDEFINITE_WAIT;
  136     return thread_cond_timedwait(cond, mutex, timeout_ms);
  137 }
  138 
  139 
  140 
  141 APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
  142 {
  143     int wake = FALSE;
  144 
  145     DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
  146 
  147     if (cond->num_waiting > cond->num_wake) {
  148         wake = TRUE;
  149         cond->num_wake++;
  150         cond->generation++;
  151     }
  152 
  153     DosReleaseMutexSem(cond->mutex);
  154 
  155     if (wake) {
  156         DosPostEventSem(cond->semaphore);
  157     }
  158 
  159     return APR_SUCCESS;
  160 }
  161 
  162 
  163 
  164 APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
  165 {
  166     unsigned long num_wake = 0;
  167 
  168     DosRequestMutexSem(cond->mutex, SEM_INDEFINITE_WAIT);
  169 
  170     if (cond->num_waiting > cond->num_wake) {
  171         num_wake = cond->num_waiting - cond->num_wake;
  172         cond->num_wake = cond->num_waiting;
  173         cond->generation++;
  174     }
  175 
  176     DosReleaseMutexSem(cond->mutex);
  177 
  178     for (; num_wake; num_wake--) {
  179         DosPostEventSem(cond->semaphore);
  180     }
  181 
  182     return APR_SUCCESS;
  183 }
  184 
  185 
  186 
  187 APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond)
  188 {
  189     return apr_pool_cleanup_run(cond->pool, cond, thread_cond_cleanup);
  190 }
  191 
  192 
  193 
  194 APR_POOL_IMPLEMENT_ACCESSOR(thread_cond)