/* * 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 #include static axis2_status_t thread_mutex_cleanup( void *data) { axutil_thread_mutex_t *lock = NULL; axutil_allocator_t *allocator = NULL; if(!data) return AXIS2_FAILURE; lock = (axutil_thread_mutex_t *)data; allocator = lock->allocator; if(lock->type == thread_mutex_critical_section) { DeleteCriticalSection(&lock->section); } else { if(!CloseHandle(lock->handle)) { return AXIS2_FAILURE; } } AXIS2_FREE(allocator, lock); return AXIS2_SUCCESS; } AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL axutil_thread_mutex_create( axutil_allocator_t * allocator, unsigned int flags) { axutil_thread_mutex_t *mutex = NULL; mutex = (axutil_thread_mutex_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t)); mutex->allocator = allocator; if(flags == AXIS2_THREAD_MUTEX_DEFAULT) /*unnested */ { /* Use an auto-reset signaled event, ready to accept one * waiting thread. */ mutex->type = thread_mutex_unnested_event; mutex->handle = CreateEvent(NULL, FALSE, TRUE, NULL); } else { /* TODO :support critical_section and nested_mutex */ } return mutex; } AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_thread_mutex_lock( axutil_thread_mutex_t * mutex) { if(mutex->type == thread_mutex_critical_section) { EnterCriticalSection(&mutex->section); } else { DWORD rv = WaitForSingleObject(mutex->handle, INFINITE); if((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) { return AXIS2_FAILURE; /*can be either BUSY or an os specific error */ } } return AXIS2_SUCCESS; } AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_thread_mutex_trylock( axutil_thread_mutex_t * mutex) { if(mutex->type == thread_mutex_critical_section) { /* TODO :implement trylock for critical section */ } else { DWORD rv = WaitForSingleObject(mutex->handle, 0); if((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) { /*can be either BUSY or an os specific error */ return AXIS2_FAILURE; } } return AXIS2_SUCCESS; } AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_thread_mutex_unlock( axutil_thread_mutex_t * mutex) { if(mutex->type == thread_mutex_critical_section) { LeaveCriticalSection(&mutex->section); } else if(mutex->type == thread_mutex_unnested_event) { if(!SetEvent(mutex->handle)) { /*os specific error */ return AXIS2_FAILURE; } } else if(mutex->type == thread_mutex_nested_mutex) { if(!ReleaseMutex(mutex->handle)) { /*os specific error */ return AXIS2_FAILURE; } } return AXIS2_SUCCESS; } AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_thread_mutex_destroy( axutil_thread_mutex_t * mutex) { return thread_mutex_cleanup((void *)mutex); }