diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-13 00:00:47 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-13 00:00:47 -0800 |
| commit | b639e4d3643b8245b77bc8707a3a864221fad195 (patch) | |
| tree | aa21c05f7ce8a1fd388b1eb1189e38e66f79e068 | |
| parent | 2bb6a23037656474a90d869c5147b32bae1a2e40 (diff) | |
| download | nng-b639e4d3643b8245b77bc8707a3a864221fad195.tar.gz nng-b639e4d3643b8245b77bc8707a3a864221fad195.tar.bz2 nng-b639e4d3643b8245b77bc8707a3a864221fad195.zip | |
Many fixes for Windows. It compiles, and some tests work.
Windows is getting there. Needs a couple of more more hours to enable
everything, especially IPC, and most of the work at this point is probably
some combination of debug and tweaking things like error handling.
| -rw-r--r-- | src/core/thread.c | 9 | ||||
| -rw-r--r-- | src/core/thread.h | 4 | ||||
| -rw-r--r-- | src/nng.c | 2 | ||||
| -rw-r--r-- | src/nng.h | 16 | ||||
| -rw-r--r-- | src/platform/posix/posix_thread.c | 15 | ||||
| -rw-r--r-- | src/platform/windows/win_impl.h | 7 | ||||
| -rw-r--r-- | src/platform/windows/win_ipc.c | 2 | ||||
| -rw-r--r-- | src/platform/windows/win_net.c | 49 | ||||
| -rw-r--r-- | src/platform/windows/win_rand.c | 2 | ||||
| -rw-r--r-- | src/platform/windows/win_thread.c | 68 | ||||
| -rw-r--r-- | tests/platform.c | 31 |
11 files changed, 81 insertions, 124 deletions
diff --git a/src/core/thread.c b/src/core/thread.c index 4a871ede..50d63521 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -38,13 +38,6 @@ nni_mtx_unlock(nni_mtx *mtx) int -nni_mtx_trylock(nni_mtx *mtx) -{ - return (nni_plat_mtx_trylock(&mtx->mtx)); -} - - -int nni_cv_init(nni_cv *cv, nni_mtx *mtx) { return (nni_plat_cv_init(&cv->cv, &mtx->mtx)); @@ -85,7 +78,7 @@ nni_cv_until(nni_cv *cv, nni_time until) void nni_cv_wake(nni_cv *cv) { - return (nni_plat_cv_wake(&cv->cv)); + nni_plat_cv_wake(&cv->cv); } diff --git a/src/core/thread.h b/src/core/thread.h index f41091a7..95794a6e 100644 --- a/src/core/thread.h +++ b/src/core/thread.h @@ -49,10 +49,6 @@ extern void nni_mtx_lock(nni_mtx *mtx); // owned by the calling thread. extern void nni_mtx_unlock(nni_mtx *mtx); -// nni_mtx_trylock attempts to acquire the given mutex. It returns -// NNG_EBUSY if the mutex is locked. -extern int nni_mtx_trylock(nni_mtx *mtx); - // nni_cv_init initializes the condition variable. The mutex supplied // must always be locked with the condition variable. extern int nni_cv_init(nni_cv *cv, nni_mtx *); @@ -252,7 +252,7 @@ nng_msg_realloc(nng_msg *msg, size_t sz) void nng_msg_free(nng_msg *msg) { - return (nni_msg_free(msg)); + nni_msg_free(msg); } @@ -30,8 +30,16 @@ extern "C" { // as a DLL, but instead linking it statically for your projects // to minimize questions about link dependencies later.) #ifndef NNG_DECL -#define NNG_DECL extern -#endif +#if defined(_WIN32) && !defined(NNG_STATIC_LIB) +#if defined(NNG_SHARED_LIB) +#define NNG_DECL __declspec(dllexport) +#else +#define NNG_DECL __declspec(dllimport) +#endif // NNG_SHARED_LIB +#else +#define NNG_DECL extern +#endif // _WIN32 && !NNG_STATIC_LIB +#endif // NNG_DECL // Types common to nng. typedef struct nng_socket nng_socket; @@ -64,10 +72,10 @@ NNG_DECL void nng_close(nng_socket *); NNG_DECL int nng_shutdown(nng_socket *); // nng_protocol returns the protocol number of the socket. -uint16_t nng_protocol(nng_socket *); +NNG_DECL uint16_t nng_protocol(nng_socket *); // nng_peer returns the protocol number for the socket's peer. -uint16_t nng_peer(nng_socket *); +NNG_DECL uint16_t nng_peer(nng_socket *); // nng_setopt sets an option for a specific socket. NNG_DECL int nng_setopt(nng_socket *, int, const void *, size_t); diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c index 0ca9c18d..a429e071 100644 --- a/src/platform/posix/posix_thread.c +++ b/src/platform/posix/posix_thread.c @@ -87,21 +87,6 @@ nni_plat_mtx_unlock(nni_plat_mtx *mtx) int -nni_plat_mtx_trylock(nni_plat_mtx *mtx) -{ - int rv; - - if ((rv = pthread_mutex_trylock(&mtx->mtx)) == EBUSY) { - return (NNG_EBUSY); - } - if (rv != 0) { - nni_panic("pthread_mutex_trylock: %s", strerror(rv)); - } - return (0); -} - - -int nni_plat_cv_init(nni_plat_cv *cv, nni_plat_mtx *mtx) { int rv; diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h index 1b306f8f..b2714b23 100644 --- a/src/platform/windows/win_impl.h +++ b/src/platform/windows/win_impl.h @@ -32,7 +32,7 @@ struct nni_plat_tcpsock { struct nni_plat_ipcsock { HANDLE p; -} +}; struct nni_plat_thr { void (__stdcall *func)(void *); @@ -47,12 +47,9 @@ struct nni_plat_mtx { struct nni_plat_cv { CONDITION_VARIABLE cv; - CRITICAL_SECTION cs; + CRITICAL_SECTION *cs; }; -#define nni_alloc(s) calloc(1, (s)) -#define nni_free(s, z) free(s) - #endif // PLATFORM_WINDOWS #endif // PLATFORM_WIN_IMPL_H diff --git a/src/platform/windows/win_ipc.c b/src/platform/windows/win_ipc.c index 9ede99e0..682eb0a8 100644 --- a/src/platform/windows/win_ipc.c +++ b/src/platform/windows/win_ipc.c @@ -126,7 +126,7 @@ void nni_plat_ipc_fini(nni_plat_ipcsock *s) { if (s->p != INVALID_HANDLE_VALUE) { - (void) CloseHandle(s->fd); + (void) CloseHandle(s->p); s->p = INVALID_HANDLE_VALUE; } } diff --git a/src/platform/windows/win_net.c b/src/platform/windows/win_net.c index 7c44c125..3bd34b78 100644 --- a/src/platform/windows/win_net.c +++ b/src/platform/windows/win_net.c @@ -16,10 +16,10 @@ static struct { int nng_err; } nni_plat_wsa_errnos[] = { - { WSAECONNABORTED, NNG_ECONNABORTED }, + { WSAECONNABORTED, NNG_ECLOSED }, { WSAEINTR, NNG_EINTR }, - { WSAEFAULT, NNG_EFAULT }, - { WSAECONNRESET, NNG_ECONNRESET }, + // REVIEW THESE!!! + { WSAECONNRESET, NNG_ECONNREFUSED }, { WSAEMSGSIZE, NNG_EINVAL }, { WSAENETDOWN, NNG_EUNREACHABLE }, { WSAENETRESET, NNG_ECLOSED }, @@ -30,7 +30,7 @@ nni_plat_wsa_errnos[] = { { WSA_INVALID_HANDLE, NNG_ECLOSED }, { WSA_NOT_ENOUGH_MEMORY, NNG_ENOMEM }, { WSA_INVALID_PARAMETER, NNG_EINVAL }, - { WSAEACCESS, NNG_EPERM }, + { WSAEACCES, NNG_EPERM }, { 0, 0 }, // MUST BE LAST }; @@ -38,13 +38,15 @@ nni_plat_wsa_errnos[] = { static int nni_plat_wsa_last_error(void) { - errnum = WSAGetLastError(); + int errnum = WSAGetLastError(); + int i; + if (errnum == 0) { return (0); } for (i = 0; nni_plat_wsa_errnos[i].nng_err != 0; i++) { if (errnum == nni_plat_wsa_errnos[i].wsa_err) { - return (nni_plat_errnos[i].nng_err); + return (nni_plat_wsa_errnos[i].nng_err); } } // Other system errno. @@ -53,7 +55,7 @@ nni_plat_wsa_last_error(void) static int -nni_plat_to_sockaddr(struct SOCKADDR_STORAGE *ss, const nni_sockaddr *sa) +nni_plat_to_sockaddr(SOCKADDR_STORAGE *ss, const nni_sockaddr *sa) { struct sockaddr_in *sin; struct sockaddr_in6 *sin6; @@ -109,7 +111,7 @@ int nni_plat_lookup_host(const char *host, nni_sockaddr *addr, int flags) { ADDRINFO hint; - ADDIRINFO *ai; + ADDRINFO *ai; memset(&hint, 0, sizeof (hint)); hint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; @@ -209,18 +211,19 @@ nni_plat_tcp_recv(nni_plat_tcpsock *s, nni_iov *iovs, int cnt) static void -nni_plat_tcp_setopts(int fd) +nni_plat_tcp_setopts(SOCKET fd) { - int one; + BOOL yes; // Don't inherit the handle (CLOEXEC really). - SetHandleInformation(s->s, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation((HANDLE) fd, HANDLE_FLAG_INHERIT, 0); // Also disable Nagle. We are careful to group data with WSASend, // and latency is king for most of our users. (Consider adding // a method to enable this later.) - one = 1; - (void) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof (one)); + yes = 1; + (void) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &yes, + sizeof (yes)); } @@ -245,7 +248,7 @@ void nni_plat_tcp_shutdown(nni_plat_tcpsock *s) { if (s->s != INVALID_SOCKET) { - (void) shutdown(s->fd, SHUT_RDWR); + (void) shutdown(s->s, SD_BOTH); } } @@ -260,9 +263,9 @@ int nni_plat_tcp_listen(nni_plat_tcpsock *s, const nni_sockaddr *addr) { int len; - struct sockaddr_storage ss; + SOCKADDR_STORAGE ss; int rv; - ULONG one; + BOOL yes; len = nni_plat_to_sockaddr(&ss, addr); if (len < 0) { @@ -279,9 +282,9 @@ nni_plat_tcp_listen(nni_plat_tcpsock *s, const nni_sockaddr *addr) // Make sure that we use the address exclusively. Windows lets // others hijack us by default. - one = 1; - if (setsocket(s->s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, &one, - sizeof (one)) == SOCKET_ERROR) { + yes = 1; + if (setsockopt(s->s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *) &yes, + sizeof (yes)) == SOCKET_ERROR) { rv = nni_plat_wsa_last_error(); (void) closesocket(s->s); s->s = INVALID_SOCKET; @@ -315,8 +318,8 @@ nni_plat_tcp_connect(nni_plat_tcpsock *s, const nni_sockaddr *addr, const nni_sockaddr *bindaddr) { int len; - struct sockaddr_storage ss; - struct sockaddr_storage bss; + SOCKADDR_STORAGE ss; + SOCKADDR_STORAGE bss; int rv; len = nni_plat_to_sockaddr(&ss, addr); @@ -342,7 +345,7 @@ nni_plat_tcp_connect(nni_plat_tcpsock *s, const nni_sockaddr *addr, return (NNG_EADDRINVAL); } if (bind(s->s, (struct sockaddr *) &bss, len) < 0) { - rv = nni_plat_wsa_last_error(errno); + rv = nni_plat_wsa_last_error(); (void) closesocket(s->s); s->s = INVALID_SOCKET; return (rv); @@ -372,7 +375,7 @@ nni_plat_tcp_accept(nni_plat_tcpsock *s, nni_plat_tcpsock *server) if (fd == INVALID_SOCKET) { err = WSAGetLastError(); - if (err == WSAECONNRESET || err == WSAEWOULDBLOCK) { + if ((err == WSAECONNRESET) || (err == WSAEWOULDBLOCK)) { continue; } return (nni_plat_wsa_last_error()); diff --git a/src/platform/windows/win_rand.c b/src/platform/windows/win_rand.c index 5ca80782..1cabb6a0 100644 --- a/src/platform/windows/win_rand.c +++ b/src/platform/windows/win_rand.c @@ -22,7 +22,7 @@ nni_plat_seed_prng(void *buf, size_t bufsz) // for use with crypto keying.) while (bufsz > sizeof (val)) { rand_s(&val); - memcmp(buf, &val); + memcpy(buf, &val, sizeof (val)); buf = (((char *)buf) + sizeof (val)); bufsz -= sizeof (val); } diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c index 2c967b84..4f323616 100644 --- a/src/platform/windows/win_thread.c +++ b/src/platform/windows/win_thread.c @@ -13,11 +13,28 @@ #ifdef PLATFORM_WINDOWS +void * +nni_alloc(size_t sz) +{ + void *v; + + v = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz); + return (v); +} + + +void +nni_free(void *b, size_t z) +{ + NNI_ARG_UNUSED(z); + HeapFree(GetProcessHeap(), 0, b); +} + + int nni_plat_mtx_init(nni_plat_mtx *mtx) { - InitializeCritialSection(&mtx->cs); - mtx->owner = 0; + InitializeCriticalSection(&mtx->cs); return (0); } @@ -25,9 +42,6 @@ nni_plat_mtx_init(nni_plat_mtx *mtx) void nni_plat_mtx_fini(nni_plat_mtx *mtx) { - if (mtx->owner != 0) { - nni_panic("cannot delete critical section: mutex owned!") - } DeleteCriticalSection(&mtx->cs); } @@ -36,42 +50,17 @@ void nni_plat_mtx_lock(nni_plat_mtx *mtx) { EnterCriticalSection(&mtx->cs); - if (mtx->owner != 0) { - nni_panic("recursive mutex entry!"); - } - mtx->owner = GetCurrentThreadId(); } void nni_plat_mtx_unlock(nni_plat_mtx *mtx) { - if (mtx->owner != GetCurrentThreadId()) { - nni_panic("cannot unlock mutex: not owner!"); - } - self->owner = 0; LeaveCriticalSection(&mtx->cs); } int -nni_plat_mtx_trylock(nni_plat_mtx *mtx) -{ - BOOL ok; - - ok = TryEnterCriticalSection(&mtx->cs); - if (!ok) { - return (NNG_EBUSY); - } - if (mtx->owner != 0) { - nni_panic("recursive trymutex entry?!?") - } - mtx->owner = GetCurrentThreadId(); - return (0); -} - - -int nni_plat_cv_init(nni_plat_cv *cv, nni_plat_mtx *mtx) { InitializeConditionVariable(&cv->cv); @@ -83,18 +72,14 @@ nni_plat_cv_init(nni_plat_cv *cv, nni_plat_mtx *mtx) void nni_plat_cv_wake(nni_plat_cv *cv) { - int rv; - - if ((rv = pthread_cond_broadcast(&cv->cv)) != 0) { - nni_panic("pthread_cond_broadcast: %s", strerror(rv)); - } + WakeAllConditionVariable(&cv->cv); } void nni_plat_cv_wait(nni_plat_cv *cv) { - (void) SleepConditionVariable(&cv->cv, &cv->cs, INFINITE); + (void) SleepConditionVariableCS(&cv->cv, cv->cs, INFINITE); } @@ -113,7 +98,7 @@ nni_plat_cv_until(nni_plat_cv *cv, nni_time until) msec = (until - now)/1000; } - ok = SleepConditionVariable(&cv->cv, &cv->cs, msec); + ok = SleepConditionVariableCS(&cv->cv, cv->cs, msec); return (ok ? 0 : NNG_ETIMEDOUT); } @@ -125,7 +110,7 @@ nni_plat_cv_fini(nni_plat_cv *cv) static unsigned int __stdcall -nni_plat_thread_main(void *arg) +nni_plat_thr_main(void *arg) { nni_plat_thr *thr = arg; @@ -164,7 +149,6 @@ nni_plat_thr_fini(nni_plat_thr *thr) int nni_plat_init(int (*helper)(void)) { - int rv; LONG old; static LONG initing = 0; static LONG inited = 0; @@ -178,16 +162,16 @@ nni_plat_init(int (*helper)(void)) // and the other will be put to sleep briefly so that the first // can complete. This is a poor man's singleton initializer, since // we can't statically initialize critical sections. - while ((old = InterlockedTestExchange(&initing, 0, 1)) != 0) { + while ((old = InterlockedCompareExchange(&initing, 0, 1)) != 0) { Sleep(1); } if (!inited) { helper(); inited = 1; } - InterlockExchange(&initing, 0); + InterlockedExchange(&initing, 0); - return (rv); + return (0); } diff --git a/tests/platform.c b/tests/platform.c index d408959c..7bf1d0d1 100644 --- a/tests/platform.c +++ b/tests/platform.c @@ -110,16 +110,14 @@ TestMain("Platform Operations", { Convey("We can lock a mutex", { nni_mtx_lock(&mx); So(1); - Convey("And cannot recursively lock", { - rv = nni_mtx_trylock(&mx); - So(rv != 0); - }) Convey("And we can unlock it", { nni_mtx_unlock(&mx); So(1); Convey("And then lock it again", { - rv = nni_mtx_trylock(&mx); - So(rv == 0); + nni_mtx_lock(&mx); + So(1); + nni_mtx_unlock(&mx); + So(1); }) }) }) @@ -138,16 +136,13 @@ TestMain("Platform Operations", { So(rv == 0); nni_thr_run(&thr); + Reset({ + nni_thr_fini(&thr); + }) + Convey("It ran", { nni_usleep(50000); // for context switch So(val == 1); - nni_thr_fini(&thr); - }) - Convey("We can reap it", { - nni_thr_fini(&thr); - }) - Reset({ - nni_thr_fini(&thr); }) }) }) @@ -162,6 +157,7 @@ TestMain("Platform Operations", { Reset({ nni_cv_fini(&arg.cv); nni_mtx_fini(&arg.mx); + nni_thr_fini(&thr); }); Convey("Notification works", { @@ -174,7 +170,7 @@ TestMain("Platform Operations", { nni_cv_wait(&arg.cv); } nni_mtx_unlock(&arg.mx); - nni_thr_fini(&thr); + nni_thr_wait(&thr); So(arg.did == 1); }) @@ -188,7 +184,7 @@ TestMain("Platform Operations", { } So(arg.did == 0); nni_mtx_unlock(&arg.mx); - nni_thr_fini(&thr); + nni_thr_wait(&thr); }) Convey("Not running works", { @@ -200,11 +196,6 @@ TestMain("Platform Operations", { } So(arg.did == 0); nni_mtx_unlock(&arg.mx); - nni_thr_fini(&thr); - }) - - Reset({ - nni_thr_fini(&thr); }) }) }) |
