00001 /******************************************************************************* 00002 * Copyright (C) 2005 Novell, Inc. All rights reserved. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * 00007 * - Redistributions of source code must retain the above copyright notice, 00008 * this list of conditions and the following disclaimer. 00009 * 00010 * - Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * 00014 * - Neither the name of Novell, Inc., nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL Novell, Inc., OR THE 00022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00027 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00028 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 *******************************************************************************/ 00030 00031 00036 #include "blocxx/BLOCXX_config.h" 00037 #include "blocxx/IPCMutex.hpp" 00038 #include "blocxx/ExceptionIds.hpp" 00039 00040 00041 namespace BLOCXX_NAMESPACE 00042 { 00043 00044 const int ADD_KEY = 1; 00045 const int BLOCK_FOR_KEY = -1; 00046 00047 BLOCXX_DEFINE_EXCEPTION_WITH_ID(IPCMutex); 00048 00049 00051 IPCMutex::IPCMutex(int semKey) 00052 { 00053 m_sbuf.sem_num = 0; 00054 m_sbuf.sem_flg = 0; 00055 m_semid = semget((key_t)semKey, 1, 0666); 00056 if (m_semid == -1) 00057 { 00058 m_semid = semget((key_t)semKey, 1, IPC_CREAT | 0666); 00059 if (m_semid == -1) 00060 { 00061 BLOCXX_THROW(IPCMutexException, 00062 "Unable to create semaphore"); 00063 return; 00064 } 00065 m_arg.val = 1; 00066 semctl(m_semid, 0, SETVAL, m_arg); 00067 } 00068 } 00069 00071 void 00072 IPCMutex::wait() 00073 { 00074 m_sbuf.sem_op = BLOCK_FOR_KEY; 00075 semop(m_semid, &m_sbuf, 1); 00076 } 00077 00079 void 00080 IPCMutex::signal() 00081 { 00082 m_sbuf.sem_op = ADD_KEY; 00083 semop(m_semid, &m_sbuf, 1); 00084 } 00085 00087 // static 00088 void 00089 IPCMutex::free(int semKey) 00090 { 00091 int semid = semget((key_t)semKey, 1, 0666); 00092 if (semid != -1) 00093 { 00094 semctl(semid, 1, IPC_RMID, 0); 00095 } 00096 } 00097 00099 IPCMutexLock::IPCMutexLock(IPCMutex& sem) 00100 : m_sem(sem) 00101 { 00102 m_sem.wait(); 00103 } 00104 00106 IPCMutexLock::~IPCMutexLock() 00107 { 00108 m_sem.signal(); 00109 } 00110 00111 }