diff --git a/qse/include/qse/sys/Makefile.am b/qse/include/qse/sys/Makefile.am index 98704c00..f34516d4 100644 --- a/qse/include/qse/sys/Makefile.am +++ b/qse/include/qse/sys/Makefile.am @@ -1,6 +1,7 @@ pkgincludedir = $(includedir)/qse/sys pkginclude_HEADERS = \ + mtx.h \ thr.h if ENABLE_CXX diff --git a/qse/include/qse/sys/Makefile.in b/qse/include/qse/sys/Makefile.in index 2b33c910..37e451c5 100644 --- a/qse/include/qse/sys/Makefile.in +++ b/qse/include/qse/sys/Makefile.in @@ -117,7 +117,7 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -am__pkginclude_HEADERS_DIST = thr.h SocketAddress.hpp +am__pkginclude_HEADERS_DIST = mtx.h thr.h SocketAddress.hpp am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -343,7 +343,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -pkginclude_HEADERS = thr.h $(am__append_1) +pkginclude_HEADERS = mtx.h thr.h $(am__append_1) all: all-am .SUFFIXES: diff --git a/qse/include/qse/sys/mtx.h b/qse/include/qse/sys/mtx.h new file mode 100644 index 00000000..ce085e76 --- /dev/null +++ b/qse/include/qse/sys/mtx.h @@ -0,0 +1,102 @@ +/* + * $Id$ + * + Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EQSERESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _QSE_CMN_MTX_H_ +#define _QSE_CMN_MTX_H_ + +#include +#include + + +#if defined(_WIN32) + typedef void* qse_mtx_hnd_t; +#elif defined(__OS2__) +# error not implemented +#elif defined(__DOS__) +# error not implemented +#elif defined(__BEOS__) + typedef sem_id qse_mtx_hnd_t; +#else +# include + typedef pthread_mutex_t qse_mtx_hnd_t; +#endif + +typedef struct qse_mtx_t qse_mtx_t; + +struct qse_mtx_t +{ + qse_mmgr_t* mmgr; + qse_mtx_hnd_t hnd; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +qse_mtx_t* qse_mtx_open ( + qse_mmgr_t* mmgr, + qse_size_t xtnsize +); + +void qse_mtx_close ( + qse_mtx_t* mtx +); + +int qse_mtx_init ( + qse_mtx_t* mtx, + qse_mmgr_t* mmgr +); + +void qse_mtx_fini ( + qse_mtx_t* mtx +); + +qse_mmgr_t* qse_mtx_getmmgr ( + qse_mtx_t* mtx +); + +void* qse_mtx_getxtn ( + qse_mtx_t* mtx +); + +int qse_mtx_lock ( + qse_mtx_t* mtx +); + +int qse_mtx_unlock ( + qse_mtx_t* mtx +); + +int qse_mtx_trylock ( + qse_mtx_t* mtx +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/qse/include/qse/sys/thr.h b/qse/include/qse/sys/thr.h index 0a6f6d26..cbfe1cb9 100644 --- a/qse/include/qse/sys/thr.h +++ b/qse/include/qse/sys/thr.h @@ -122,6 +122,14 @@ void qse_thr_fini ( qse_thr_t* thr ); +qse_mmgr_t* qse_thr_getmmgr ( + qse_thr_t* thr +); + +void* qse_thr_getxtn ( + qse_thr_t* thr +); + qse_size_t qse_thr_getstacksize ( qse_thr_t* thr ); diff --git a/qse/lib/sys/Makefile.am b/qse/lib/sys/Makefile.am index c6125562..9d070ad0 100644 --- a/qse/lib/sys/Makefile.am +++ b/qse/lib/sys/Makefile.am @@ -6,6 +6,7 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libqsesys.la libqsesys_la_SOURCES = \ + mtx.c \ thr.c \ thr.h libqsesys_la_LDFLAGS = -L../cmn -version-info 1:0:0 -no-undefined diff --git a/qse/lib/sys/Makefile.in b/qse/lib/sys/Makefile.in index 00751d8b..8151ffeb 100644 --- a/qse/lib/sys/Makefile.in +++ b/qse/lib/sys/Makefile.in @@ -127,7 +127,7 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libqsesys_la_DEPENDENCIES = -am_libqsesys_la_OBJECTS = thr.lo +am_libqsesys_la_OBJECTS = mtx.lo thr.lo libqsesys_la_OBJECTS = $(am_libqsesys_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -407,6 +407,7 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libqsesys.la $(am__append_1) libqsesys_la_SOURCES = \ + mtx.c \ thr.c \ thr.h @@ -500,6 +501,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketAddress.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtx.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thr.Plo@am__quote@ .c.o: diff --git a/qse/lib/sys/mtx.c b/qse/lib/sys/mtx.c new file mode 100644 index 00000000..9baccf74 --- /dev/null +++ b/qse/lib/sys/mtx.c @@ -0,0 +1,204 @@ +/* + * $Id$ + * + Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "../cmn/mem.h" + +#if (!defined(__unix__) && !defined(__unix)) || defined(HAVE_PTHREAD) + +#if defined(_WIN32) + #include +#elif defined(__BEOS__) + #include +#else + #if defined(AIX) && defined(__GNUC__) + typedef int crid_t; + typedef unsigned int class_id_t; + #endif + #include +#endif + + +qse_mtx_t* qse_mtx_open (qse_mmgr_t* mmgr, qse_size_t xtnsize) +{ + qse_mtx_t* mtx; + + mtx = (qse_mtx_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_mtx_t) + xtnsize); + if (mtx) + { + if (qse_mtx_init (mtx, mmgr) <= -1) + { + QSE_MMGR_FREE (mmgr, mtx); + return QSE_NULL; + } + else QSE_MEMSET (QSE_XTN(mtx), 0, xtnsize); + } + + return mtx; +} + +void qse_mtx_close (qse_mtx_t* mtx) +{ + qse_mtx_fini (mtx); + QSE_MMGR_FREE (mtx->mmgr, mtx); +} + + +int qse_mtx_init (qse_mtx_t* mtx, qse_mmgr_t* mmgr) +{ + QSE_MEMSET (mtx, 0, QSE_SIZEOF(*mtx)); + mtx->mmgr = mmgr; + +#if defined(_WIN32) + mtx->hnd = CreateMutex (QSE_NULL, FALSE, QSE_NULL); + if (mtx->hnd == QSE_NULL) return -1; + +#elif defined(__OS2__) +# error not implemented + +#elif defined(__DOS__) +# error not implemented + +#elif defined(__BEOS__) + mtx->hnd = create_sem (1, QSE_NULL); + if (mtx->hnd < B_OK) return -1; + +#else + /* + qse_ensure (pthread_mutexattr_init (&attr) == 0); + if (pthread_mutexattr_settype (&attr, type) != 0) + { + int num = qse_geterrno(); + pthread_mutexattr_destroy (&attr); + if (mtx->__dynamic) qse_free (mtx); + qse_seterrno (num); + return QSE_NULL; + } + qse_ensure (pthread_mutex_init (&mtx->hnd, &attr) == 0); + qse_ensure (pthread_mutexattr_destroy (&attr) == 0); + */ + if (pthread_mutex_init (&mtx->hnd, QSE_NULL) != 0) return -1; +#endif + + return 0; +} + +void qse_mtx_fini (qse_mtx_t* mtx) +{ +#if defined(_WIN32) + CloseHandle (mtx->hnd); + +#elif defined(__OS2__) +# error not implemented + +#elif defined(__DOS__) +# error not implemented + +#elif defined(__BEOS__) + /*if (delete_sem(mtx->hnd) != B_NO_ERROR) return -1;*/ + delete_sem(mtx->hnd); + +#else + pthread_mutex_destroy(&mtx->hnd); +#endif +} + +qse_mmgr_t* qse_mtx_getmmgr (qse_mtx_t* mtx) +{ + return mtx->mmgr; +} + +void* qse_mtx_getxtn (qse_mtx_t* mtx) +{ + return QSE_XTN (mtx); +} + +int qse_mtx_lock (qse_mtx_t* mtx) +{ +#if defined(_WIN32) + /* + * MSDN + * WAIT_ABANDONED The specified object is a mutex object that was + * not released by the thread that owned the mutex + * object before the owning thread terminated. + * Ownership of the mutex object is granted to the + * calling thread, and the mutex is set to nonsignaled. + * WAIT_OBJECT_0 The state of the specified object is signaled. + * WAIT_TIMEOUT The time-out interval elapsed, and the object's + * state is nonsignaled. + * WAIT_FAILED An error occurred + */ + if (WaitForSingleObject ( + mtx->hnd, INFINITE) == WAIT_FAILED) + { + qse_seterrno (qse_maperrno(GetLastError())); + return -1; + } +#elif defined(__BEOS__) + if (acquire_sem(mtx->hnd) != B_NO_ERROR) return -1; +#else + if (pthread_mutex_lock (&mtx->hnd) != 0) return -1; +#endif + return 0; +} + +int qse_mtx_unlock (qse_mtx_t* mtx) +{ +#if defined(_WIN32) + if (ReleaseMutex (mtx->hnd) == FALSE) + { + qse_seterrno (qse_maperrno(GetLastError())); + return -1; + } +#elif defined(__BEOS__) + if (release_sem(mtx->hnd) != B_NO_ERROR) return -1; +#else + if (pthread_mutex_unlock (&mtx->hnd) != 0) return -1; +#endif + return 0; +} + +int qse_mtx_trylock (qse_mtx_t* mtx) +{ +#if defined(_WIN32) + if (WaitForSingleObject(mtx->hnd,0) != WAIT_OBJECT_0) + { + qse_seterrno (qse_maperrno(GetLastError())); + return -1; + } +#elif defined(__BEOS__) + if (acquire_sem_etc(mtx->hnd,1,B_ABSOLUTE_TIMEOUT,0) != B_NO_ERROR) + { + /* TODO: check for B_WOULD_BLOCK */ + return -1; + } +#else + if (pthread_mutex_trylock(&mtx->hnd) != 0) return -1; +#endif + return 0; +} + +#endif diff --git a/qse/lib/sys/thr.c b/qse/lib/sys/thr.c index 1d488e67..c892c64f 100644 --- a/qse/lib/sys/thr.c +++ b/qse/lib/sys/thr.c @@ -78,6 +78,15 @@ void qse_thr_fini (qse_thr_t* thr) thr->__handle = QSE_THR_HND_INVALID; } +qse_mmgr_t* qse_thr_getmmgr (qse_thr_t* thr) +{ + return thr->mmgr; +} + +void* qse_thr_getxtn (qse_thr_t* thr) +{ + return QSE_XTN (thr); +} qse_size_t qse_thr_getstacksize (qse_thr_t* thr) {