⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread_rwlock.c

📁 apache的软件linux版本
💻 C
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include "apr.h"#include "apr_private.h"#include "apr_general.h"#include "apr_strings.h"#include "win32/apr_arch_thread_rwlock.h"#include "apr_portable.h"static apr_status_t thread_rwlock_cleanup(void *data){    apr_thread_rwlock_t *rwlock = data;        if (! CloseHandle(rwlock->read_event))        return apr_get_os_error();    if (! CloseHandle(rwlock->write_mutex))        return apr_get_os_error();        return APR_SUCCESS;}APR_DECLARE(apr_status_t)apr_thread_rwlock_create(apr_thread_rwlock_t **rwlock,                                                  apr_pool_t *pool){    *rwlock = apr_palloc(pool, sizeof(**rwlock));    (*rwlock)->pool        = pool;    (*rwlock)->readers     = 0;    if (! ((*rwlock)->read_event = CreateEvent(NULL, TRUE, FALSE, NULL))) {        *rwlock = NULL;        return apr_get_os_error();    }    if (! ((*rwlock)->write_mutex = CreateMutex(NULL, FALSE, NULL))) {        CloseHandle((*rwlock)->read_event);        *rwlock = NULL;        return apr_get_os_error();    }    apr_pool_cleanup_register(pool, *rwlock, thread_rwlock_cleanup,                              apr_pool_cleanup_null);    return APR_SUCCESS;}static apr_status_t apr_thread_rwlock_rdlock_core(apr_thread_rwlock_t *rwlock,                                                  DWORD  milliseconds){    DWORD   code = WaitForSingleObject(rwlock->write_mutex, milliseconds);    if (code == WAIT_FAILED || code == WAIT_TIMEOUT)        return APR_FROM_OS_ERROR(code);    /* We've successfully acquired the writer mutex, we can't be locked     * for write, so it's OK to add the reader lock.  The writer mutex     * doubles as race condition protection for the readers counter.        */    InterlockedIncrement(&rwlock->readers);        if (! ResetEvent(rwlock->read_event))        return apr_get_os_error();        if (! ReleaseMutex(rwlock->write_mutex))        return apr_get_os_error();        return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_thread_rwlock_rdlock(apr_thread_rwlock_t *rwlock){    return apr_thread_rwlock_rdlock_core(rwlock, INFINITE);}APR_DECLARE(apr_status_t) apr_thread_rwlock_tryrdlock(apr_thread_rwlock_t *rwlock){    return apr_thread_rwlock_rdlock_core(rwlock, 0);}static apr_status_t apr_thread_rwlock_wrlock_core(apr_thread_rwlock_t *rwlock, DWORD milliseconds){    DWORD   code = WaitForSingleObject(rwlock->write_mutex, milliseconds);    if (code == WAIT_FAILED || code == WAIT_TIMEOUT)        return APR_FROM_OS_ERROR(code);    /* We've got the writer lock but we have to wait for all readers to     * unlock before it's ok to use it.     */    if (rwlock->readers) {        /* Must wait for readers to finish before returning, unless this         * is an trywrlock (milliseconds == 0):         */        code = milliseconds          ? WaitForSingleObject(rwlock->read_event, milliseconds)          : WAIT_TIMEOUT;                if (code == WAIT_FAILED || code == WAIT_TIMEOUT) {            /* Unable to wait for readers to finish, release write lock: */            if (! ReleaseMutex(rwlock->write_mutex))                return apr_get_os_error();                        return APR_FROM_OS_ERROR(code);        }    }    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_thread_rwlock_wrlock(apr_thread_rwlock_t *rwlock){    return apr_thread_rwlock_wrlock_core(rwlock, INFINITE);}APR_DECLARE(apr_status_t)apr_thread_rwlock_trywrlock(apr_thread_rwlock_t *rwlock){    return apr_thread_rwlock_wrlock_core(rwlock, 0);}APR_DECLARE(apr_status_t) apr_thread_rwlock_unlock(apr_thread_rwlock_t *rwlock){    apr_status_t rv = 0;    /* First, guess that we're unlocking a writer */    if (! ReleaseMutex(rwlock->write_mutex))        rv = apr_get_os_error();        if (rv == APR_FROM_OS_ERROR(ERROR_NOT_OWNER)) {        /* Nope, we must have a read lock */        if (rwlock->readers &&            ! InterlockedDecrement(&rwlock->readers) &&            ! SetEvent(rwlock->read_event)) {            rv = apr_get_os_error();        }        else {            rv = 0;        }    }    return rv;}APR_DECLARE(apr_status_t) apr_thread_rwlock_destroy(apr_thread_rwlock_t *rwlock){    return apr_pool_cleanup_run(rwlock->pool, rwlock, thread_rwlock_cleanup);}APR_POOL_IMPLEMENT_ACCESSOR(thread_rwlock)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -