log4cplus  1.1.0
syncprims-win32.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //  Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved.
00003 //  
00004 //  Redistribution and use in source and binary forms, with or without modifica-
00005 //  tion, are permitted provided that the following conditions are met:
00006 //  
00007 //  1. Redistributions of  source code must  retain the above copyright  notice,
00008 //     this list of conditions and the following disclaimer.
00009 //  
00010 //  2. 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 //  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00015 //  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00016 //  FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
00017 //  APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
00018 //  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
00019 //  DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
00020 //  OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
00021 //  ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
00022 //  (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
00023 //  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024 
00030 
00031 #include <stdexcept>
00032 
00033 
00034 namespace log4cplus { namespace thread { namespace impl {
00035 
00036 
00037 //
00038 //
00039 //
00040 
00041 inline
00042 bool
00043 InitializeCriticalSection_wrapInternal (LPCRITICAL_SECTION cs)
00044 {
00045 #if defined (_MSC_VER)
00046     __try
00047     {
00048 #endif
00049 
00050     InitializeCriticalSection (cs);
00051 
00052 #if defined (_MSC_VER)
00053     }
00054     __except (GetExceptionCode() == STATUS_NO_MEMORY
00055         ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
00056     {
00057         return false;
00058     }
00059 #endif
00060 
00061     return true;
00062 }
00063 
00064 
00065 inline
00066 void
00067 InitializeCriticalSection_wrap (LPCRITICAL_SECTION cs)
00068 {
00069     if (! InitializeCriticalSection_wrapInternal (cs))
00070         throw std::runtime_error (
00071             "InitializeCriticalSection: STATUS_NO_MEMORY");
00072 }
00073 
00074 
00075 inline
00076 Mutex::Mutex (log4cplus::thread::Mutex::Type)
00077 {
00078     InitializeCriticalSection_wrap (&cs);
00079 }
00080 
00081 
00082 inline
00083 Mutex::~Mutex ()
00084 {
00085     DeleteCriticalSection (&cs);
00086 }
00087 
00088 
00089 inline
00090 void
00091 Mutex::lock () const
00092 {
00093     EnterCriticalSection (&cs);
00094 }
00095 
00096 
00097 inline
00098 void
00099 Mutex::unlock () const
00100 {
00101     LeaveCriticalSection (&cs);
00102 }
00103 
00104 
00105 //
00106 //
00107 //
00108 
00109 inline
00110 Semaphore::Semaphore (unsigned max, unsigned initial)
00111 {
00112     sem = CreateSemaphore (0, initial, max, 0);
00113     if (! sem)
00114         LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore");
00115 }
00116 
00117 
00118 inline
00119 Semaphore::~Semaphore ()
00120 {
00121     try
00122     {
00123         if (! CloseHandle (sem))
00124             LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore");
00125     }
00126     catch (...)
00127     { }
00128 }
00129 
00130 
00131 inline
00132 void
00133 Semaphore::unlock () const
00134 {
00135     DWORD ret = ReleaseSemaphore (sem, 1, 0);
00136     if (! ret)
00137          LOG4CPLUS_THROW_RTE ("Semaphore::unlock");
00138 }
00139 
00140 
00141 inline
00142 void
00143 Semaphore::lock () const
00144 {
00145     DWORD ret = WaitForSingleObject (sem, INFINITE);
00146     if (ret != WAIT_OBJECT_0)
00147         LOG4CPLUS_THROW_RTE ("Semaphore::lock");
00148 }
00149 
00150 
00151 //
00152 //
00153 //
00154 
00155 
00156 inline
00157 FairMutex::FairMutex ()
00158 {
00159     mtx = CreateMutex (0, false, 0);
00160     if (! mtx)
00161         LOG4CPLUS_THROW_RTE ("FairMutex::FairMutex");
00162 }
00163 
00164 
00165 inline
00166 FairMutex::~FairMutex ()
00167 {
00168     try
00169     {
00170         if (! CloseHandle (mtx))
00171             LOG4CPLUS_THROW_RTE ("FairMutex::~FairMutex");
00172     }
00173     catch (...)
00174     { }
00175 }
00176 
00177 
00178 inline
00179 void
00180 FairMutex::lock () const
00181 {
00182     DWORD ret = WaitForSingleObject (mtx, INFINITE);
00183     if (ret != WAIT_OBJECT_0)
00184         LOG4CPLUS_THROW_RTE ("FairMutex::lock");
00185 }
00186 
00187 
00188 inline
00189 void
00190 FairMutex::unlock () const
00191 {
00192     if (! ReleaseMutex (mtx))
00193         LOG4CPLUS_THROW_RTE ("FairMutex::unlock");
00194 }
00195 
00196 
00197 //
00198 //
00199 //
00200 
00201 inline
00202 ManualResetEvent::ManualResetEvent (bool sig)
00203 {
00204     ev = CreateEvent (0, true, sig, 0);
00205     if (! ev)
00206         LOG4CPLUS_THROW_RTE ("ManualResetEvent::ManualResetEvent");
00207 }
00208 
00209 
00210 inline
00211 ManualResetEvent::~ManualResetEvent ()
00212 {
00213     try
00214     {
00215         if (! CloseHandle (ev))
00216             LOG4CPLUS_THROW_RTE ("ManualResetEvent::~ManualResetEvent");
00217     }
00218     catch (...)
00219     { }
00220 }
00221 
00222 
00223 inline
00224 void
00225 ManualResetEvent::signal () const
00226 {
00227     if (! SetEvent (ev))
00228         LOG4CPLUS_THROW_RTE ("ManualResetEVent::signal");
00229 }
00230 
00231 
00232 inline
00233 void
00234 ManualResetEvent::wait () const
00235 {
00236     DWORD ret = WaitForSingleObject (ev, INFINITE);
00237     if (ret != WAIT_OBJECT_0)
00238         LOG4CPLUS_THROW_RTE ("ManualResetEvent::wait");
00239 }
00240 
00241 
00242 inline
00243 bool
00244 ManualResetEvent::timed_wait (unsigned long msec) const
00245 {
00246     DWORD ret = WaitForSingleObject (ev, static_cast<DWORD>(msec));
00247     switch(ret)
00248     {
00249     case WAIT_OBJECT_0:
00250         return true;
00251 
00252     case WAIT_TIMEOUT:
00253         return false;
00254 
00255     default:
00256         LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
00257         // Silence warnings about not returning any value from function
00258         // returning bool.
00259         return false;
00260     }
00261 }
00262 
00263 
00264 inline
00265 void
00266 ManualResetEvent::reset () const
00267 {
00268     if (! ResetEvent (ev))
00269         LOG4CPLUS_THROW_RTE ("ManualResetEvent::reset");
00270 }
00271 
00272 
00273 //
00274 //
00275 //
00276 
00277 #if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX)
00278 #include "log4cplus/thread/impl/syncprims-pmsm.h"
00279 
00280 #else
00281 inline
00282 SharedMutex::SharedMutex ()
00283 {
00284     InitializeSRWLock (&srwl);
00285 }
00286 
00287 
00288 inline
00289 SharedMutex::~SharedMutex ()
00290 { }
00291 
00292 
00293 inline
00294 void
00295 SharedMutex::rdlock () const
00296 {
00297     AcquireSRWLockShared (&srwl);
00298 }
00299 
00300 
00301 inline
00302 void
00303 SharedMutex::rdunlock () const
00304 {
00305     ReleaseSRWLockShared (&srwl);
00306 }
00307 
00308 
00309 inline
00310 void
00311 SharedMutex::wrlock () const
00312 {
00313     AcquireSRWLockExclusive (&srwl);
00314 }
00315 
00316 
00317 inline
00318 void
00319 SharedMutex::wrunlock () const
00320 {
00321     ReleaseSRWLockExclusive (&srwl);
00322 }
00323 
00324 
00325 #endif
00326 
00327 
00328 } } } // namespace log4cplus { namespace thread { namespace impl {