/// \brief Releases an aquired lock on the mutex void unlock() { WINSTL_ASSERT(NULL != m_mx); if(!::ReleaseMutex(m_mx)) { DWORD const e = ::GetLastError(); #ifdef STLSOFT_CF_EXCEPTION_SUPPORT # if STLSOFT_LEAD_VER >= 0x010a0000 STLSOFT_THROW_X(synchronisation_object_state_change_failed_exception(e, "mutex release failed", Synchronisation_MutexReleaseFailed)); # else /* ? STLSOFT_LEAD_VER >= 1.10 */ STLSOFT_THROW_X(synchronisation_exception("mutex release failed", e)); # endif /* STLSOFT_LEAD_VER >= 1.10 */ #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ } }
ss_explicit_k module(S const& moduleName, int mode = RTLD_NOW) : m_hmodule(load(moduleName, mode)) { # ifdef STLSOFT_CF_EXCEPTION_SUPPORT if(NULL == m_hmodule) { STLSOFT_THROW_X(unix_exception("Cannot load module", errno)); } # endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ }
/// \brief Releases an aquired lock on the semaphore, increasing the /// semaphore's counter by one. void unlock() { UNIXSTL_ASSERT(NULL != m_sem); if(::sem_post(m_sem) < 0) { #ifdef STLSOFT_CF_EXCEPTION_SUPPORT STLSOFT_THROW_X(synchronisation_exception("semaphore release failed", errno)); #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ } }
/// \brief Sets the state of the event to signalled void reset() { WINSTL_ASSERT(NULL != m_ev); if(!::ResetEvent(m_ev)) { #ifdef STLSOFT_CF_EXCEPTION_SUPPORT STLSOFT_THROW_X(synchronisation_exception("event reset operation failed", ::GetLastError())); #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ } }
/// \brief Acquires a lock on the mutex, pending the thread until the lock is aquired ws_bool_t lock(ws_dword_t wait) { WINSTL_ASSERT(NULL != m_mx); DWORD const dwRes = ::WaitForSingleObject(m_mx, wait); if(WAIT_ABANDONED == dwRes) { m_bAbandoned = true; return true; } else { m_bAbandoned = false; if(WAIT_TIMEOUT == dwRes) { return false; } else { if(WAIT_OBJECT_0 != dwRes) { DWORD const e = ::GetLastError(); #ifdef STLSOFT_CF_EXCEPTION_SUPPORT # if STLSOFT_LEAD_VER >= 0x010a0000 STLSOFT_THROW_X(wait_failed_logic_exception(e, "mutex wait failed")); # else /* ? STLSOFT_LEAD_VER >= 1.10 */ STLSOFT_THROW_X(synchronisation_exception("mutex wait failed", e)); # endif /* STLSOFT_LEAD_VER >= 1.10 */ #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ } return true; } } }
/// \brief Attempts to lock the mutex /// /// \return <b>true</b> if the mutex was aquired, or <b>false</b> if not. /// /// \exception unixstl::synchronisation_exception When compiling with exception support, this will throw /// unixstl::synchronisation_exception if the lock cannot be acquired for a reason /// other than a timeout (<code>EBUSY</code>). When compiling absent /// exception support, failure to acquire the lock (for any other /// reason) will be reflected in a non-zero return from get_error(). bool try_lock() { m_error = ::pthread_mutex_trylock(m_mx); if(0 == m_error) { return true; } else { #ifdef STLSOFT_CF_EXCEPTION_SUPPORT if(EBUSY != m_error) { STLSOFT_THROW_X(synchronisation_exception("Mutex try-lock failed", m_error)); } #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ return false; } }
/// \brief Attempts to lock the semaphore /// /// \return <b>true</b> if the semaphore was aquired, or <b>false</b> if not bool_type try_lock() { UNIXSTL_ASSERT(NULL != m_sem); int res = ::sem_trywait(m_sem); if(0 == res) { return true; } else { if(EAGAIN != res) { #ifdef STLSOFT_CF_EXCEPTION_SUPPORT STLSOFT_THROW_X(synchronisation_exception("semaphore wait failed", errno)); #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ } } return false; }
char const* check_description_a_() { if( NULL == m_description_a && NULL != m_description) { int cch = ::WideCharToMultiByte(0, 0, m_description, -1, NULL, 0, NULL, NULL); m_description_a = static_cast<char*>(::CoTaskMemAlloc((1 + cch) * sizeof(char))); if(NULL == m_description_a) { #ifdef STLSOFT_CF_THROW_BAD_ALLOC STLSOFT_THROW_X(stlsoft_ns_qual_std(bad_alloc)()); #endif /* STLSOFT_CF_THROW_BAD_ALLOC */ } else { ::WideCharToMultiByte(0, 0, m_description, -1, m_description_a, 1 + cch, NULL, NULL); } } return (NULL == m_description_a) ? "" : m_description_a; }
char const* make_message_( int e ) { #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS char buff[1001]; int const e2 = ::strerror_s(buff, e); char* const r = ::_strdup((0 == e2) ? buff : "unknown failure"); if(NULL == r) { STLSOFT_THROW_X(std::bad_alloc()); } context_ = r; return r; #else /* ? STLSOFT_USING_SAFE_STR_FUNCTIONS */ context_ = NULL; return ::strerror(e); #endif /* STLSOFT_USING_SAFE_STR_FUNCTIONS */ }
/// Translates a CMemoryException* into a std::bad_alloc& static void handle(CMemoryException *) { STLSOFT_THROW_X(mfcstl_ns_qual_std(bad_alloc)()); }
inline ws_uint64_t load_text_file_impl(S1 const& fileName, S2 &contents) { typedef string_traits<S1> string_traits_t; STLSOFT_STATIC_ASSERT(sizeof(string_traits_t)); // Fires if S1 does not have a traits specialisation defined typedef string_traits<S2> string_traits2_t; STLSOFT_STATIC_ASSERT(sizeof(string_traits2_t)); // Fires if S2 does not have a traits specialisation defined typedef ss_typename_type_k string_traits_t::char_type C; STLSOFT_STATIC_ASSERT(sizeof(C)); // Fires if the traits is not correctly defined typedef ss_typename_type_k string_traits2_t::char_type char_2_type; STLSOFT_STATIC_ASSERT(sizeof(char_2_type)); // Fires if the traits is not correctly defined typedef filesystem_traits<C> filesys_traits_t; STLSOFT_STATIC_ASSERT(sizeof(filesys_traits_t)); // Fires if no corresponding filesystem_traits defined scoped_handle<HANDLE> h( filesys_traits_t::create_file( stlsoft_ns_qual(c_str_ptr)(fileName) , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , 0 , NULL) , (void (STLSOFT_CDECL *)(HANDLE))&filesys_traits_t::close_handle // This cast required by VC++ 5 , INVALID_HANDLE_VALUE); if(INVALID_HANDLE_VALUE == h.get()) { STLSOFT_THROW_X(windows_exception("File does not exist", ::GetLastError())); } ws_uint64_t size = filesys_traits_t::get_file_size(h.get()); if( 0 != size && static_cast<ws_uint64_t>(~0) != size) { if(size > 0xFFFFFFFF) { STLSOFT_THROW_X(winstl_ns_qual_std(out_of_range)("Cannot read in files larger than 4GB")); } else { // TODO: Catch the out-of-memory exception and translate to a std::out_of_range() typedef ::stlsoft::auto_buffer_old< char_2_type , processheap_allocator<char_2_type> , 1024 > buffer_t; buffer_t buffer(static_cast<ss_typename_type_k buffer_t::size_type>(size)); DWORD dw; if(!::ReadFile(h.get(), &buffer[0], buffer.size(), &dw, NULL)) { STLSOFT_THROW_X(windows_exception("Read operation failed", ::GetLastError())); } else { contents.assign(&buffer[0], dw); return size; } } } return 0; }