diff --git a/.gitignore b/.gitignore index a3c30f016..8da930c91 100755 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,9 @@ iguana/tests/.priv2wif.swp agents/libiguana.a iguana/iguana_rpc.o-2ed461a0 +agents/win32/iguana.exe +agents/win32/libcrypto777.a +agents/win32/confs/.tmpmarker +agents/win32/DB/.tmpmarker +agents/win32/DB/purgeable/.tmpmarker +agents/* diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index f92b8a2ec..6b1dfac75 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -20,6 +20,7 @@ #include #include #include +#define HAVE_STRUCT_TIMESPEC #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#define HAVE_STRUCT_TIMESPEC #include //#include //#include "in.h" diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index d65f54350..0782c3f2a 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -45,9 +45,9 @@ struct tm *gmtime_r(const time_t *timep,struct tm *result) return(p); } -struct tm *_gmtime32(const time_t *timep,struct tm *result) { return(gmtime_r(timep,result)); } -time_t _time32(struct tm *tm) { return(time(NULL)); } -time_t _localtime32(struct tm *tm) { return(time(NULL)); } +//struct tm *_gmtime32(const time_t *timep,struct tm *result) { return(gmtime_r(timep,result)); } +//time_t _time32(struct tm *tm) { return(time(NULL)); } +//time_t _localtime32(struct tm *tm) { return(time(NULL)); } #include #include // portable: uint64_t MSVC: __int64 diff --git a/crypto777/hmac/tomcrypt_custom.h b/crypto777/hmac/tomcrypt_custom.h index 7a8644cd2..c3d812906 100755 --- a/crypto777/hmac/tomcrypt_custom.h +++ b/crypto777/hmac/tomcrypt_custom.h @@ -371,8 +371,8 @@ /* THREAD management */ #ifdef LTC_PTHREAD - -//#include +#define HAVE_STRUCT_TIMESPEC +#include #define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; #define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; diff --git a/crypto777/make_win32 b/crypto777/make_win32 index d9e99b05a..40c3ace92 100644 --- a/crypto777/make_win32 +++ b/crypto777/make_win32 @@ -6,9 +6,9 @@ all: clean build build : mkdir -p ../agents/win32 || true @echo "\nBuilding crypto777....." - $(TOOL_DIR)/$(MINGW)-gcc -w -D __MINGW -c $(CRYPTO777_SRCS) -I/usr/mingw32/include -I/usr/mingw32/include/sys -I/home/user/SuperNET/includes/openssl -I/home/user/SuperNET/crypto777 || (echo -e "\033[4mERROR: Compilation failed for win32 \033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -D __MINGW -DHAVE_STRUCT_TIMESPEC -c $(CRYPTO777_SRCS) -I$(TOOL_DIR)/include -I$(APP)/includes/openssl -I$(APP)/crypto777 || (echo -e "\033[4mERROR: Compilation failed for win32 \033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o || (echo -e "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o || (echo -e "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) @echo "\Build Successful......" diff --git a/crypto777/make_win64 b/crypto777/make_win64 index e9d12a629..38f30ca90 100644 --- a/crypto777/make_win64 +++ b/crypto777/make_win64 @@ -6,9 +6,9 @@ all: clean build build: mkdir -p ../agents/win64 || true @echo "\nBuilding crypto......" - $(TOOL_DIR)/$(MINGW)-gcc -w -D __MINGW -c $(CRYPTO777_SRCS) -I/usr/share/mingw-w64/include -I /usr/share/mingw-w64/include/sys -I/home/user/SuperNET/includes/openssl || (echo "\033[4m ERROR: Compilation failed for win64\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -D __MINGW -DHAVE_STRUCT_TIMESPEC -c $(CRYPTO777_SRCS) -I$(TOOL_DIR)/include -I$(APP)/includes/openssl || (echo "\033[4m ERROR: Compilation failed for win64\033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-ar rcu ../agents/win64/libcrypto777.a *.o || (echo "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW)-ar rcu ../agents/win64/libcrypto777.a *.o || (echo "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) clean: diff --git a/crypto777/mingw b/crypto777/mingw index e5a3bc40f..3e4e9a5a3 100755 --- a/crypto777/mingw +++ b/crypto777/mingw @@ -1,6 +1,6 @@ include crypto777.sources all: - $(TOOL_DIR)/$(MINGW)-gcc -w -D __MINGW -c $(CRYPTO777_SRCS) -I/usr/mingw32/include -I/usr/mingw32/include/sys -I/home/user/SuperNET/includes/openssl -I/home/user/SuperNET/crypto777 - $(TOOL_DIR)/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o + $(TOOL_DIR)/bin/$(MINGW) -w -D __MINGW -c $(CRYPTO777_SRCS) -I$(TOOL_DIR)/include -I$(APP)/includes/openssl -I$(APP)/crypto777 + $(TOOL_DIR)/bin/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o rm *.o diff --git a/crypto777/nanosrc/core/global.c b/crypto777/nanosrc/core/global.c index 0d457b208..51ab91709 100755 --- a/crypto777/nanosrc/core/global.c +++ b/crypto777/nanosrc/core/global.c @@ -79,6 +79,7 @@ #include #if defined NN_HAVE_MINGW +#define HAVE_STRUCT_TIMESPEC #include #elif defined NN_HAVE_WINDOWS #define gmtime_r(ptr_numtime, ptr_strtime) gmtime_s(ptr_strtime, ptr_numtime) diff --git a/crypto777/nanosrc/utils/glock.c b/crypto777/nanosrc/utils/glock.c index 7fe0c6dc3..21de524a6 100755 --- a/crypto777/nanosrc/utils/glock.c +++ b/crypto777/nanosrc/utils/glock.c @@ -51,7 +51,7 @@ void nn_glock_unlock (void) #else #include "err.h" - +#define HAVE_STRUCT_TIMESPEC #include static pthread_mutex_t nn_glock_mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/crypto777/nanosrc/utils/mutex.h b/crypto777/nanosrc/utils/mutex.h index b65de4105..f6083ee8a 100755 --- a/crypto777/nanosrc/utils/mutex.h +++ b/crypto777/nanosrc/utils/mutex.h @@ -26,6 +26,7 @@ #ifdef NN_HAVE_WINDOWS #include "win.h" #else +#define HAVE_STRUCT_TIMESPEC #include #endif diff --git a/crypto777/nanosrc/utils/sem.h b/crypto777/nanosrc/utils/sem.h index 82b8454df..38932e110 100755 --- a/crypto777/nanosrc/utils/sem.h +++ b/crypto777/nanosrc/utils/sem.h @@ -40,7 +40,7 @@ void nn_sem_post (struct nn_sem *self); int nn_sem_wait (struct nn_sem *self); #if defined __APPLE__ || defined __PNACL - +#define HAVE_STRUCT_TIMESPEC #include struct nn_sem { diff --git a/crypto777/nanosrc/utils/thread_posix.h b/crypto777/nanosrc/utils/thread_posix.h index c007fa02c..b76a99c7b 100755 --- a/crypto777/nanosrc/utils/thread_posix.h +++ b/crypto777/nanosrc/utils/thread_posix.h @@ -19,7 +19,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +#define HAVE_STRUCT_TIMESPEC #include struct nn_thread diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index cc32ac670..8104903b6 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -408,7 +408,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) { while ( (result= bind(sock,(struct sockaddr*)&saddr,addrlen)) != 0 ) { - if ( errno == EADDRINUSE ) + /* if ( errno == EADDRINUSE ) { sleep(1); printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); @@ -421,7 +421,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) } sleep(13); //continue; - } + } */ if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) { printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); diff --git a/iguana/main.c b/iguana/main.c index 0f7e06a43..fcda90b9a 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -20,7 +20,7 @@ #define CHROMEAPP_JSON iguana_JSON #define CHROMEAPP_HANDLER Handler_iguana #define ACTIVELY_DECLARE - +#define HAVE_STRUCT_TIMESPEC #include "../pnacl_main.h" #include "iguana777.h" diff --git a/iguana/make_win32 b/iguana/make_win32 index e2209cb0e..48abe809c 100644 --- a/iguana/make_win32 +++ b/iguana/make_win32 @@ -6,10 +6,10 @@ all: clean check build build: @echo "\nBuilding iguana......" - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) -lws2_32 -lpthread -DHAVE_STRUCT_TIMESPEC || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win32/iguana.exe + $(TOOL_DIR)/bin/strip --strip-all ../agents/win32/iguana.exe @echo "\nBuild successfully......" check: diff --git a/iguana/make_win64 b/iguana/make_win64 index cd8d3f1fe..046ccfc60 100644 --- a/iguana/make_win64 +++ b/iguana/make_win64 @@ -1,16 +1,16 @@ include iguana.sources include ../mingw.path64 -LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2_64.a ../agents/win64/libcrypto777.a ../win/libcurldll.a /usr/share/mingw-w64/lib/libws2_32.a /usr/share/mingw-w64/lib/libgdi32.a -I/usr/share/mingw-w64/include -I/usr/i386/include -I/usr/i386/include/curl -I/home/user/SuperNET/iguana -I/home/user/SuperNET/includes -I/home/user/SuperNET/crypto777 +LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2_64.a ../agents/win64/libcrypto777.a ../win/libcurldll.a $(TOOL_DIR)/lib/libws2_32.a $(TOOL_DIR)/lib/libgdi32.a -I$(TOOL_DIR)/include -I/usr/i386/include -I/usr/i386/include/curl -I$(APP)/iguana -I$(APP)/includes -I$(APP)/crypto777 include mingw64_inc all: check build build: - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) -lws2_32 -lpthread -DHAVE_STRUCT_TIMESPEC || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win64/iguana.exe || (echo -e "\033[4mERROR: Failed to strip iguana\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/strip --strip-all ../agents/win64/iguana.exe || (echo -e "\033[4mERROR: Failed to strip iguana\033[0m"; exit 1; ) check: diff --git a/iguana/mingw b/iguana/mingw index 50a9812e0..e27e46990 100755 --- a/iguana/mingw +++ b/iguana/mingw @@ -1,6 +1,6 @@ include iguana.sources all: - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win32/iguana.exe + $(TOOL_DIR)/bin/$(MINGW) -w -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) -lws2_32 -lpthread + $(TOOL_DIR)/bin/strip --strip-all ../agents/win32/iguana.exe diff --git a/iguana/mingw32 b/iguana/mingw32 index c14867059..65c26246c 100755 --- a/iguana/mingw32 +++ b/iguana/mingw32 @@ -1,4 +1,4 @@ include ../mingw.path -LIBS := /usr/share/mingw-w64/lib/libpthread.a ../agents/win32/libcrypto777.a /usr/i586-mingw32msvc/lib/libws2_32.a /usr/i586-mingw32msvc/lib/libgdi32.a -I/usr/mingw32/include -I/usr/i386/include -I/home/user/SuperNET/iguana -I/home/user/SuperNET/includes -I/home/user/SuperNET/crypto777 +LIBS := $(TOOL_DIR)/lib/libpthread.a ../agents/win32/libcrypto777.a $(TOOL_DIR)/lib/libws2_32.a $(TOOL_DIR)/lib/libgdi32.a -I$(TOOL_DIR)/include -I$(APP)/iguana -I$(APP)/includes -I$(APP)/crypto777 include mingw diff --git a/iguana/mingw64 b/iguana/mingw64 index a29a3cdb3..cf851d9c0 100755 --- a/iguana/mingw64 +++ b/iguana/mingw64 @@ -1,3 +1,3 @@ include ../mingw.path64 -LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2_64.a ../agents/win64/libcrypto777.a ../win/libcurldll.a /usr/share/mingw-w64/lib/libws2_32.a /usr/share/mingw-w64/lib/libgdi32.a -I/usr/share/mingw-w64/include -I/usr/i386/include -I/usr/i386/include/curl -I/home/user/SuperNET/iguana -I/home/user/SuperNET/includes -I/home/user/SuperNET/crypto777 +LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2_64.a ../agents/win64/libcrypto777.a ../win/libcurldll.a $(TOOL_DIR)/lib/libws2_32.a $(TOOL_DIR)/lib/libgdi32.a -I$(TOOL_DIR)/include -I/usr/i386/include -I/usr/i386/include/curl -I$(APP)/iguana -I$(APP)/includes -I$(APP)/crypto777 include mingw64_inc diff --git a/iguana/mingw64_inc b/iguana/mingw64_inc index 4993450e2..d8a4c85d6 100755 --- a/iguana/mingw64_inc +++ b/iguana/mingw64_inc @@ -1,6 +1,6 @@ include iguana.sources all: - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win64/iguana.exe + $(TOOL_DIR)/bin/$(MINGW) -w -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) -lws2_32 -lpthread + $(TOOL_DIR)/bin/strip --strip-all ../agents/win64/iguana.exe diff --git a/mingw.path b/mingw.path index 0f758932e..8d28d7be4 100755 --- a/mingw.path +++ b/mingw.path @@ -1,2 +1,3 @@ -TOOL_DIR := /usr/bin -MINGW := i586-mingw32msvc +TOOL_DIR := /D/MinGW +MINGW := mingw32-gcc +APP := /C/Users/usamir/Documents/GitHub/SuperNET diff --git a/mingw.path64 b/mingw.path64 index 713a49292..4a454339c 100755 --- a/mingw.path64 +++ b/mingw.path64 @@ -1,2 +1,3 @@ -TOOL_DIR := /usr/bin -MINGW := i686-w64-mingw32 +TOOL_DIR := /D/MinGW +MINGW := mingw32-gcc +APP := /C/Users/usamir/Documents/GitHub/SuperNET \ No newline at end of file diff --git a/win/libcrypto.a b/win/libcrypto.a new file mode 100644 index 000000000..62f2adfc8 Binary files /dev/null and b/win/libcrypto.a differ diff --git a/win/libcurl.a b/win/libcurl.a new file mode 100644 index 000000000..768133dde Binary files /dev/null and b/win/libcurl.a differ diff --git a/win/libcurldll.a b/win/libcurldll.a new file mode 100644 index 000000000..15cf86362 Binary files /dev/null and b/win/libcurldll.a differ diff --git a/win/libpthreadGC2.a b/win/libpthreadGC2.a new file mode 100644 index 000000000..df211759f Binary files /dev/null and b/win/libpthreadGC2.a differ diff --git a/win/libpthreadGC2_64.a b/win/libpthreadGC2_64.a new file mode 100644 index 000000000..430162364 Binary files /dev/null and b/win/libpthreadGC2_64.a differ diff --git a/win/libsecp256k1.a b/win/libsecp256k1.a new file mode 100644 index 000000000..778d5d980 Binary files /dev/null and b/win/libsecp256k1.a differ diff --git a/win/libssl.a b/win/libssl.a new file mode 100644 index 000000000..ac3e692a7 Binary files /dev/null and b/win/libssl.a differ diff --git a/win/mingw.c b/win/mingw.c new file mode 100644 index 000000000..d9f51c831 --- /dev/null +++ b/win/mingw.c @@ -0,0 +1,743 @@ +#ifdef __MINGW32__ + +#include "mingw.h" + +#undef socket +#undef connect +#undef accept +#undef shutdown + +#include +#include +#include + +int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) +{ + struct timeval timeout, *toptr; + fd_set ifds, ofds, efds, *ip, *op; + unsigned int i, rc; + + /* Set up the file-descriptor sets in ifds, ofds and efds. */ + FD_ZERO(&ifds); + FD_ZERO(&ofds); + FD_ZERO(&efds); + for (i = 0, op = ip = 0; i < nfds; ++i) { + fds[i].revents = 0; + if(fds[i].events & (POLLIN|POLLPRI)) { + ip = &ifds; + FD_SET(fds[i].fd, ip); + } + if(fds[i].events & POLLOUT) { + op = &ofds; + FD_SET(fds[i].fd, op); + } + FD_SET(fds[i].fd, &efds); + } + + /* Set up the timeval structure for the timeout parameter */ + if(timo < 0) { + toptr = 0; + } else { + toptr = &timeout; + timeout.tv_sec = timo / 1000; + timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; + } + +#ifdef DEBUG_POLL + printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); +#endif + rc = select(0, ip, op, &efds, toptr); +#ifdef DEBUG_POLL + printf("Exiting select rc=%d\n", rc); +#endif + + if(rc <= 0) + return rc; + + if(rc > 0) { + for ( i = 0; i < nfds; ++i) { + int fd = fds[i].fd; + if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + fds[i].revents |= POLLIN; + if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + fds[i].revents |= POLLOUT; + if(FD_ISSET(fd, &efds)) + /* Some error was detected ... should be some way to know. */ + fds[i].revents |= POLLHUP; +#ifdef DEBUG_POLL + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); +#endif + } + } + return rc; +} +static void +set_connect_errno(int winsock_err) +{ + switch(winsock_err) { + case WSAEINVAL: + case WSAEALREADY: + case WSAEWOULDBLOCK: + errno = EINPROGRESS; + break; + default: + errno = winsock_err; + break; + } +} + +static void +set_socket_errno(int winsock_err) +{ + switch(winsock_err) { + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + default: + errno = winsock_err; + break; + } +} +/* + * A wrapper around the socket() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +SOCKET +win32_socket(int domain, int type, int protocol) +{ + SOCKET fd = socket(domain, type, protocol); + if(fd == INVALID_SOCKET) { + set_socket_errno(WSAGetLastError()); + } + return fd; +} +/* + * A wrapper around the connect() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +int +win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) +{ + int rc = connect(fd, addr, addr_len); + assert(rc == 0 || rc == SOCKET_ERROR); + if(rc == SOCKET_ERROR) { + set_connect_errno(WSAGetLastError()); + } + return rc; +} + +/* + * A wrapper around the accept() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +SOCKET +win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) +{ + SOCKET newfd = accept(fd, addr, addr_len); + if(newfd == INVALID_SOCKET) { + set_socket_errno(WSAGetLastError()); + newfd = -1; + } + return newfd; +} + +/* + * A wrapper around the shutdown() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +int +win32_shutdown(SOCKET fd, int mode) +{ + int rc = shutdown(fd, mode); + assert(rc == 0 || rc == SOCKET_ERROR); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + +int win32_close_socket(SOCKET fd) +{ + int rc = closesocket(fd); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + +ssize_t win32_write_socket(SOCKET fd, void *buf, int n) +{ + int rc = send(fd, buf, n, 0); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + +ssize_t win32_read_socket(SOCKET fd, void *buf, int n) +{ + int rc = recv(fd, buf, n, 0); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + + +char * win32_strtok_r(char *s, const char *delim, char **lasts) +{ + register char *spanp; + register int c, sc; + char *tok; + + + if (s == NULL && (s = *lasts) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *lasts = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *lasts = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +char *win32_strsep (char **stringp, const char *delim) +{ + register char *s; + register const char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#ifdef noneed +/****************************************************************************** + time32.c -- extended time functions that use all 32 bits + + Author: Mark Baranowski + Email: requestXXX@els-software.org (remove XXX) + Download: http://els-software.org + + Last significant change: May 6, 2015 + + These functions are provided "as is" in the hopes that they might serve some + higher purpose. If you want these functions to serve some lower purpose, + then that too is all right. So as to keep these hopes alive you may + freely distribute these functions so long as this header remains intact. + You may also freely distribute modified versions of these functions so long + as you indicate that such versions are modified and so long as you + provide access to the unmodified original copy. + + Note: The most recent version of these functions may be obtained from + http://els-software.org + + The following functions support Unix time beyond Jan 19 03:14:08 2038 GMT, + assuming that the future standard will treat the 32-bits used by Unix's + present-day file system as unsigned. + + These functions work by mapping years within the region 2038-2106 down + into the region of 2010-2037. All fields of the "tm" structure, + including those fields dealing with day-of-week and daylight savings time + are correct! Bear in mind, however, that the definition of daylight + savings time changes with the whims of man, thus the notion of daylight + savings held during 2010-2037 may not be the same as the notion held + thereafter. + + See also: time(3) + + ****************************************************************************/ + +#include "sysdefs.h" + +#include "defs.h" +#include "time32.h" +#include "sysInfo.h" + +/*****************************************************************************/ +#if defined(HAVE_LONG_LONG_TIME) + +struct tm *localtime32_r(const time_t *clock, struct tm *res) +{return localtime_r(clock, res);} + +struct tm *gmtime32_r(const time_t *clock, struct tm *res) +{return gmtime_r(clock, res);} + +#ifdef USE_POSIX_TIME_R +char *asctime32_r(const struct tm *tm, char *buf) +{return asctime_r(tm, buf);} + +char *ctime32_r(const time_t *clock, char *buf) +{return ctime_r(clock, buf);} +#else +char *asctime32_r(const struct tm *tm, char *buf, int buflen) +{return asctime_r(tm, buf, buflen);} + +char *ctime32_r(const time_t *clock, char *buf, int buflen) +{return ctime_r(clock, buf, buflen);} +#endif + +struct tm *localtime32(const time_t *clock) +{return localtime(clock);} + +struct tm *gmtime32(const time_t *clock) +{return gmtime(clock);} + +size_t strftime32(char *str, size_t max, + const char *format, const struct tm *tm) +{return strftime(str, max, format, tm);} + +char *asctime32(const struct tm *tm) +{return asctime(tm);} + +char *ctime32(const time_t *clock) +{return ctime(clock);} + +#ifdef HAVE_MKTIME +time_t mktime32(const struct tm *tm) +{return mktime(tm);} +#endif + +#ifdef HAVE_TIMELOCAL +/* FreeBSD/Darwin do NOT declare these args as "const": */ +time_t timelocal32(struct tm *tm) +{return timelocal(tm);} + +time_t timegm32(struct tm *tm) +{return timegm(tm);} +#endif + +/*****************************************************************************/ +#else + +Local void mapclock32(time_t *clock, int *years); +Local void mapyears32(int *years, time_t *clock); + +#if !defined(HAVE_TIME_R) +struct tm *localtime_r(const time_t *clock, struct tm *xtime); +struct tm *gmtime_r(const time_t *clock, struct tm *xtime); +# ifdef USE_POSIX_TIME_R +char *asctime_r(const struct tm *tm, char *buf); +char *ctime_r(const time_t *clock, char *buf); +# else +char *asctime_r(const struct tm *tm, char *buf, int buflen); +char *ctime_r(const time_t *clock, char *buf, int buflen); +# endif +#endif /* !defined(HAVE_TIME_R) */ + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct tm *localtime32_r(const time_t *clock, struct tm *xtime) +{ + time_t xclock = *clock; + int xyears; + mapclock32(&xclock, &xyears); + localtime_r(&xclock, xtime); + xtime->tm_year += xyears; + return(xtime); +} + + +struct tm *localtime32(const time_t *clock) +{ + static struct tm xtime; /* return value must be static */ + return(localtime32_r(clock, &xtime)); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +struct tm *gmtime32_r(const time_t *clock, struct tm *xtime) +{ + time_t xclock = *clock; + int xyears; + mapclock32(&xclock, &xyears); + gmtime_r(&xclock, xtime); + xtime->tm_year += xyears; + return(xtime); +} + + +struct tm *gmtime32(const time_t *clock) +{ + static struct tm xtime; /* return value must be static */ + return(gmtime32_r(clock, &xtime)); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* NB: strftime32 will work correctly for all years > 2038 IF and only + IF the "tm" parameter given it was generated using one of the + time32 functions: localtime32(), localtime32_r(), gmtime32(), or + gmtime32_r(). */ +/* NB: strftime() is known to be in SunOS4/5, HPUX10/11, Linux2.2/4/6; + So far Only SunOS5 is known to have cftime() and ascftime() */ +size_t strftime32(char *str, size_t max, + const char *format, const struct tm *tm) +{ +#if defined(SUNOS) + /* SunOS 5.8, 5.9, 5.10 has a quirk where "strftime(..., ..., "%a", tm)" + corrupts tzname[0] and tzname[1] for certain values of tm_year, e.g. + "edate -C 0xd0700000" currupts tzname[], but "edate -C 0xd0800000" + doesn't. Setting tm_year within spec fixes this problem, but creates + a different problem if asked to print the year. All other OSes + including SunOS5.7 appear to take tm_year at face value. */ + if (osVersion == 0) osVersion = get_osVersion(); + if (osVersion >= 50800) + { + struct tm xtime = *tm; + time_t xclock = 0; + mapyears32(&xtime.tm_year, &xclock); + return(strftime(str, max, format, &xtime)); + } +#endif + /* Fall through for OS versions that take tm_year at face value: */ + return(strftime(str, max, format, tm)); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* NB: asctime32() and asctime32_r() will work correctly for all years > 2038 + IF and only IF the "tm" parameter given it was generated using one of the + time32 functions: localtime32(), localtime32_r(), gmtime32(), or + gmtime32_r(). */ + +#ifdef USE_POSIX_TIME_R +char *asctime32_r(const struct tm *tm, char *buf) +{ + return(asctime_r(tm, buf)); +} +#else +char *asctime32_r(const struct tm *tm, char *buf, int buflen) +{ + return(asctime_r(tm, buf, buflen)); +} +#endif + + +char *asctime32(const struct tm *tm) +{ +# define BUF_SIZE (26+8) /* 8 bytes of slack */ + static char buf[BUF_SIZE]; /* return value must be static */ +#ifdef USE_POSIX_TIME_R + return(asctime32_r(tm, buf)); +#else + return(asctime32_r(tm, buf, BUF_SIZE)); +#endif +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifdef USE_POSIX_TIME_R +char *ctime32_r(const time_t *clock, char *buf) +{ + struct tm xtime; + return(asctime32_r(localtime32_r(clock, &xtime), buf)); +} +#else +char *ctime32_r(const time_t *clock, char *buf, int buflen) +{ + struct tm xtime; + return(asctime32_r(localtime32_r(clock, &xtime), buf, buflen)); +} +#endif + + +char *ctime32(const time_t *clock) +{ +# define BUF_SIZE (26+8) /* 8 bytes of slack */ + static char buf[BUF_SIZE]; /* return value must be static */ +#ifdef USE_POSIX_TIME_R + return(ctime32_r(clock, buf)); +#else + return(ctime32_r(clock, buf, BUF_SIZE)); +#endif +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* mktime is known to be supported by: HPUX 10+, SunOS5+, Linux2.2+, OSF1 + mktime is known to NOT be supported by: SunOS4 */ +#ifdef HAVE_MKTIME +time_t mktime32(const struct tm *tm) +{ + struct tm xtime = *tm; + time_t xclock; + mapyears32(&xtime.tm_year, &xclock); + return(mktime(&xtime) + xclock); +} +#endif /*HAVE_MKTIME*/ + + +/* timelocal and timegm are only known to be supported by SunOS4. Perhaps + older BSD-based OSes also support them, but POSIX based UNIXes do not. */ +#ifdef HAVE_TIMELOCAL +time_t timelocal32(struct tm *tm) +{ + struct tm xtime = *tm; + time_t xclock; + mapyears32(&xtime.tm_year, &xclock); + return(timelocal(&xtime) + xclock); +} + + +time_t timegm32(struct tm *tm) +{ + struct tm xtime = *tm; + time_t xclock; + mapyears32(&xtime.tm_year, &xclock); + return(timegm(&xtime) + xclock); +} +#endif /*HAVE_TIMELOCAL*/ + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define _28_YEARS ( 28 * SECS_PER_YEAR) +#define _68_YEARS ( 68 * SECS_PER_YEAR) +#define _90_YEARS ( 88 * SECS_PER_YEAR + 2*365*SECS_PER_DAY) +#define _96_YEARS ( 96 * SECS_PER_YEAR) +#define JAN_1_2100 (128 * SECS_PER_YEAR + 2*365*SECS_PER_DAY) +#define JAN_1_2102 (JAN_1_2100 + 2*365*SECS_PER_DAY) /* leap year missing */ +#define JAN_1_2106 (JAN_1_2102 + 4*SECS_PER_YEAR) +#define TIME32 ((Ulong)0x80000000) + +Local void mapclock32(time_t *clock, int *years) +{ + Ulong xclock = (Ulong)*clock; + int xyears = 0; + + /* Prevent certain processors (e.g. DEC_ALPHA) from sign extending: */ + if (sizeof(Ulong) > 4) xclock &= 0xffffffff; + + /* Years from 1970 up until Jan 19 03:14:08 2038 GMT need no mapping. */ + + if (xclock >= TIME32) + { + /* Map years beyond Jan 19 03:14:08 2038 GMT: */ + if (xclock >= JAN_1_2100) + { + if (xclock < JAN_1_2102) + { + /* Map years 2100 and 2101: + (These two years must be contiguously mapped in order for + localtime(JAN_1_2101) to return the correct "tm_yday" value. + Hint: think about how Jan 1 2101, 00:00 GMT maps into + Dec 31 2100 LOCAL TIME). */ + + xclock -= _90_YEARS; + xyears = 90; + } + else if (xclock < JAN_1_2106) + { + /* Map years from 2102 up until 2106: */ + xclock -= _68_YEARS; + xclock += SECS_PER_DAY; /* Compensate for missing leap year in 2100! */ + xyears = 68; + } + else + { + /* Map years from Jan 1 2106 up until Feb 7 04:28:14 2106 GMT: */ + xclock -= _96_YEARS; + xclock += SECS_PER_DAY; /* Compensate for missing leap year in 2100! */ + xyears = 96; + } + } + else + { + /* Map years from 2038 up until 2100: */ + while (xclock >= TIME32) + { + xclock -= _28_YEARS; + xyears += 28; + } + } + } + + *clock = xclock; + *years = xyears; + return; +} + + +#define _1970 ( 70) +#define _2038 ( 68 + _1970) +#define _2100 (130 + _1970) +#define _2102 (132 + _1970) +#define _2106 (136 + _1970) + +Local void mapyears32(int *years, time_t *clock) +{ + Ulong xclock = 0; + int xyears = *years; + + /* Years from 1970 up until Jan 19 03:14:08 2038 GMT need no mapping. */ + + if (xyears >= _2038) + { + /* Map years beyond Jan 19 03:14:08 2038 GMT: */ + if (xyears >= _2100) + { + if (xyears < _2102) + { + /* Map years 2100 and 2101: + (These two years must be contiguously mapped in order for + localtime(JAN_1_2101) to return the correct "tm_yday" value. + Hint: think about how Jan 1 2101, 00:00 GMT maps into + Dec 31 2100 LOCAL TIME). */ + + xyears -= 90; + xclock = _90_YEARS; + } + else if (xyears < _2106) + { + /* Map years from 2102 up until 2106: */ + xyears -= 68; + xclock = _68_YEARS; + xclock -= SECS_PER_DAY; /* Compensate for missing leap year in 2100! */ + } + else + { + /* Map years from Jan 1 2106 up until Feb 7 04:28:14 2106 GMT: */ + xyears -= 96; + xclock = _96_YEARS; + xclock -= SECS_PER_DAY; /* Compensate for missing leap year in 2100! */ + } + } + else + { + /* Map years from 2038 up until 2100: */ + while (xyears >= _2038) + { + xyears -= 28; + xclock += _28_YEARS; + } + } + } + + *years = xyears; + *clock = xclock; + return; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* The following ERSATZ *time_r() routines localtime_r(), gmtime_r(), + asctime_r(), and ctime_r() are provided here as cheap substitutes to be + used ONLY by those Unixes that are lacking these functions. Moreover, + when building on a Unix that has NATIVE support for the following ERSATZ + functions be sure to define HAVE_TIME_R so that the compiler will instead + make use of its NATIVE *time_r() routines. + + NOTE: If you must resort to using the following ERSATZ *time_r() routines + then as a consequence the *time32_r() functions in the previous section + will not be fully reentrant. HOWEVER, if you can AVOID using the + following routines and instead make use of your Unix's NATIVE *time_r() + routines then as a result the *time32_r() in the previous section will + also be reentrant! */ + +#if !defined(HAVE_TIME_R) + +struct tm *localtime_r(const time_t *clock, struct tm *xtime) +{ + *xtime = *localtime(clock); + return(xtime); +} +struct tm *gmtime_r(const time_t *clock, struct tm *xtime) +{ + *xtime = *gmtime(clock); + return(xtime); +} + +#include +# ifdef USE_POSIX_TIME_R +char *asctime_r(const struct tm *tm, char *buf) +{ + strcpy(buf, asctime(tm)); + return(buf); +} +char *ctime_r(const time_t *clock, char *buf) +{ + strcpy(buf, ctime(clock)); + return(buf); +} +# else +char *asctime_r(const struct tm *tm, char *buf, int buflen) +{ + strncpy(buf, asctime(tm), buflen); + return(buf); +} +char *ctime_r(const time_t *clock, char *buf, int buflen) +{ + strncpy(buf, ctime(clock), buflen); + return(buf); +} +# endif + +#endif /* !defined(HAVE_TIME_R) */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*****************************************************************************/ +#endif /* !defined(HAVE_LONG_LONG_TIME) */ + +#endif +#endif + + diff --git a/win/mingw.h b/win/mingw.h new file mode 100644 index 000000000..1a80c56dc --- /dev/null +++ b/win/mingw.h @@ -0,0 +1,76 @@ +#ifndef MINGW_H +#define MINGW_H + +#include + +#define _USE_W32_SOCKETS 1 +#include +#include "pthread.h" + +#define ENOTCONN WSAENOTCONN +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ENOBUFS WSAENOBUFS +#define ECONNRESET WSAECONNRESET +#define ESHUTDOWN WSAESHUTDOWN +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define EINPROGRESS WSAEINPROGRESS +#define EISCONN WSAEISCONN +#define ECONNREFUSED WSAECONNREFUSED +#define EHOSTUNREACH WSAEHOSTUNREACH + + +/* winsock doesn't feature poll(), so there is a version implemented + * in terms of select() in mingw.c. The following definitions + * are copied from linux man pages. A poll() macro is defined to + * call the version in mingw.c. + */ +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ +struct pollfd { + SOCKET fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +#define poll(x, y, z) win32_poll(x, y, z) + +/* These wrappers do nothing special except set the global errno variable if + * an error occurs (winsock doesn't do this by default). They set errno + * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code + * outside of this file "shouldn't" have to worry about winsock specific error + * handling. + */ +//#define socket(x, y, z) win32_socket(x, y, z) +//#define connect(x, y, z) win32_connect(x, y, z) +//#define accept(x, y, z) win32_accept(x, y, z) +//#define shutdown(x, y) win32_shutdown(x, y) +//#define read(x, y, z) win32_read_socket(x, y, z) +//#define write(x, y, z) win32_write_socket(x, y, z) + +/* Winsock uses int instead of the usual socklen_t */ +typedef int socklen_t; + +int win32_poll(struct pollfd *, unsigned int, int); +//SOCKET win32_socket(int, int, int); +//int win32_connect(SOCKET, struct sockaddr*, socklen_t); +//SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); +//int win32_shutdown(SOCKET, int); +//int win32_close_socket(SOCKET fd); + +//#define strtok_r(x, y, z) win32_strtok_r(x, y, z) +//#define strsep(x,y) win32_strsep(x,y) + +char *win32_strtok_r(char *s, const char *delim, char **lasts); +char *win32_strsep(char **stringp, const char *delim); + +ssize_t win32_read_socket(SOCKET fd, void *buf, int n); +ssize_t win32_write_socket(SOCKET fd, void *buf, int n); + +//static inline void sleep(unsigned ms) { Sleep(ms*1000); } + +#endif + diff --git a/win/mman.h b/win/mman.h new file mode 100644 index 000000000..94337dac0 --- /dev/null +++ b/win/mman.h @@ -0,0 +1,51 @@ + +#ifndef _SYS_MMAN_H_ +#define _SYS_MMAN_H_ + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +/* All the headers include this file. */ +#ifndef _MSC_VER +#include <_mingw.h> +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xf +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + +/* Flags for msync. */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); +int munmap(void *addr, size_t len); +int _mprotect(void *addr, size_t len, int prot); +int msync(void *addr, size_t len, int flags); +int mlock(const void *addr, size_t len); +int munlock(const void *addr, size_t len); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/win/pthread.h b/win/pthread.h new file mode 100644 index 000000000..cad8bc541 --- /dev/null +++ b/win/pthread.h @@ -0,0 +1,1368 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,9,1,0 +#define PTW32_VERSION_STRING "2, 9, 1, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#if !defined(RC_INVOKED) + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(_UWIN) +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_PTW32_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#if defined(PTW32_INCLUDE_WINDOWS_H) +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +typedef unsigned long ULONG_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if defined(HAVE_PTW32_CONFIG_H) +#include "config.h" +#endif /* HAVE_PTW32_CONFIG_H */ + +#if !defined(NEED_FTIME) +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if defined(HAVE_SIGNAL_H) +#include +#endif /* HAVE_SIGNAL_H */ + +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#if !defined(ENOTSUP) +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#if !defined(ETIMEDOUT) +# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ +#endif + +#if !defined(ENOSYS) +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#if !defined(EDEADLK) +# if defined(EDEADLOCK) +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +/* POSIX 2008 - related to robust mutexes */ +#if !defined(EOWNERDEAD) +# define EOWNERDEAD 43 +#endif +#if !defined(ENOTRECOVERABLE) +# define ENOTRECOVERABLE 44 +#endif + +#include "sched.h" + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#if !defined(PTW32_INCLUDE_WINDOWS_H) +#if !defined(HANDLE) +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#if !defined(DWORD) +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#if !defined(HAVE_STRUCT_TIMESPEC) +#define HAVE_STRUCT_TIMESPEC +#if !defined(_TIMESPEC_DEFINED) +#define _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif /* _TIMESPEC_DEFINED */ +#endif /* HAVE_STRUCT_TIMESPEC */ + +#if !defined(SIG_BLOCK) +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#if !defined(SIG_UNBLOCK) +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#if !defined(SIG_SETMASK) +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200809L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200809L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200809L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200809L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200809L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in , which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_mutexattr_{get,set}robust + */ + PTHREAD_MUTEX_STALLED = 0, /* Default */ + PTHREAD_MUTEX_ROBUST = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *)(size_t) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#if defined(__CLEANUP_SEH) + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_C) + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#if defined(__CLEANUP_CXX) + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, + int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(PTW32_CDECL *start) (void *), + void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, + void (PTW32_CDECL *init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + ptw32_cleanup_callback_t routine, + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, + void (PTW32_CDECL *destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( + pthread_mutexattr_t *attr, + int robust); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( + const pthread_mutexattr_t * attr, + int * robust); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); + +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); +PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { + PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ + PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); +/* + * Returns the win32 thread ID for POSIX thread. + */ +PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#if !defined(_UWIN) +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# if !defined(errno) +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#if defined(__cplusplus) + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if !defined(PTW32_BUILD) + +#if defined(__CLEANUP_SEH) + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_CXX) + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#if defined(_MSC_VER) + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#if !defined(PtW32NoCatchWarn) + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #if defined(PtW32CatchAll)") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#if defined(PTW32__HANDLE_DEF) +# undef HANDLE +#endif +#if defined(PTW32__DWORD_DEF) +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/win/pthreadGC2.dll b/win/pthreadGC2.dll new file mode 100644 index 000000000..67b9289df Binary files /dev/null and b/win/pthreadGC2.dll differ diff --git a/win/pthreadGC2_64.dll b/win/pthreadGC2_64.dll new file mode 100644 index 000000000..841d4a216 Binary files /dev/null and b/win/pthreadGC2_64.dll differ diff --git a/win/sched.h b/win/sched.h new file mode 100644 index 000000000..f36a97a66 --- /dev/null +++ b/win/sched.h @@ -0,0 +1,183 @@ +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(_SCHED_H) +#define _SCHED_H + +#undef PTW32_SCHED_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_SCHED_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_SCHED_LEVEL +#define PTW32_SCHED_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_SCHED_LEVEL +#define PTW32_SCHED_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_SCHED_LEVEL_MAX 3 + +#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) +#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX +/* Include everything */ +#endif + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ + +#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) +# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX +/* For pid_t */ +# include +/* Required by Unix 98 */ +# include +# else + typedef int pid_t; +# endif +#else + typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int __cdecl sched_yield (void); + +PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); + +PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); + +PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_SCHED_LEVEL +#undef PTW32_SCHED_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/win/semaphore.h b/win/semaphore.h new file mode 100644 index 000000000..c6e9407e2 --- /dev/null +++ b/win/semaphore.h @@ -0,0 +1,169 @@ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_SEMAPHORE_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_SEMAPHORE_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_SEMAPHORE_LEVEL +#define PTW32_SEMAPHORE_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_SEMAPHORE_LEVEL +#define PTW32_SEMAPHORE_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_SEMAPHORE_LEVEL_MAX 3 + +#if !defined(PTW32_SEMAPHORE_LEVEL) +#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(__GNUC__) && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined(HAVE_MODE_T) +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int __cdecl sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_unlink (const char * name); + +PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, + int * sval); + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_SEMAPHORE_LEVEL +#undef PTW32_SEMAPHORE_LEVEL_MAX + +#endif /* !SEMAPHORE_H */