fixes #647 Initial cmake support for non-Windows platforms

This change is the first step towards a unified CMake based build for
all nanomsg platforms.  With this it is possible to build nanomsg
using cmake on at least Linux, MacOS X, illumos, and Windows systems.
However, there remains work to be done, particularly with respect to
delivery of documentation and the nanocat binary.

The eventual goal will be to remove support for the autotools, and
settle on a single cmake based toolchain.

This work is the result of a collaborative effort by several authors:
Jack R. Dunaway (@JackDunaway), Garrett D'Amore (@gdamore),
Franklin Mathieu (@Snaipe) and Shiva (@shiva).
diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 0000000..05e2430
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,22 @@
+version: 0.8.{build}
+environment:
+  matrix:
+    # array of all environments used to test builds
+    - GENERATOR: Visual Studio 14 2015
+      CFG: Debug
+    - GENERATOR: Visual Studio 12 2013
+      CFG: Debug
+    - GENERATOR: Visual Studio 14 2015 Win64
+      CFG: Debug
+    - GENERATOR: Visual Studio 12 2013 Win64
+      CFG: Debug
+build:
+  parallel: true
+build_script:
+  - cmd: cmake --version
+  - cmd: md build
+  - cmd: cd build
+  - cmd: cmake -G "%GENERATOR%" ..
+  - cmd: cmake --build .
+test_script:
+  - cmd: ctest --output-on-failure -C "%CFG%"
diff --git a/.travis.yml b/.travis.yml
index e156a1e..7055e80 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,12 +1,28 @@
 language: c
 sudo: false
-compiler:
-- clang
-- gcc
+matrix:
+  include:
+    - os: linux
+      compiler: gcc
+    - os: linux
+      compiler: clang
+#    - os: osx
+#      compiler: gcc
+    - os: osx
+      compiler: clang
 script:
-- ./autogen.sh
-- ./configure
-- make distcheck
+  # Print all environment variables to aid in CI development
+  - printenv
+  # Print version and available CMake generators to aid in CI development
+  - cmake --version
+  - cmake --help
+  # Perform out-of-source build
+  - mkdir build
+  - cd build
+  # Perform CMake backend generation, build, and test
+  - cmake ..
+  - cmake --build .
+  - ctest --output-on-failure -C Debug
 deploy:
   provider: releases
   api_key:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f9b7ac..519f6eb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,7 @@
 #
 #   Copyright (c) 2012 Martin Sustrik  All rights reserved.
 #   Copyright (c) 2013 GoPivotal, Inc.  All rights reserved.
+#   Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved.
 #   Copyright 2016 Garrett D'Amore <garrett@damore.org>
 #
 #   Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,35 +23,185 @@
 #   IN THE SOFTWARE.
 #
 
-cmake_minimum_required (VERSION 2.8)
-include (CheckIncludeFiles)
+cmake_minimum_required (VERSION 2.8.7)
+include (CheckFunctionExists)
 include (CheckSymbolExists)
+include (CheckStructHasMember)
+include (CheckLibraryExists)
 include (CheckCSourceCompiles)
 
 project (nanomsg C)
 enable_testing ()
 
-#  Platform checks.
+set (ISSUE_REPORT_MSG "Please consider opening an issue at https://github.com/nanomsg/nanomsg with your findings")
 
-if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
-    add_definitions (-DNN_HAVE_WINDOWS)
-    add_definitions (-D_CRT_SECURE_NO_WARNINGS)
+# Determine library versions.
 
-    if (MINGW)
-        add_definitions (-DNN_HAVE_MINGW -DNN_HAVE_STDINT -D_WIN32_WINNT=0x0600)
-    endif ()
+file (READ src/nn.h NN_HDR_STR)
+string (REGEX REPLACE ".*#define +NN_VERSION_CURRENT +([0-9]+).*" "\\1" NN_VERSION_CURRENT "${NN_HDR_STR}")
+string (REGEX REPLACE ".*#define +NN_VERSION_REVISION +([0-9]+).*" "\\1" NN_VERSION_REVISION "${NN_HDR_STR}")
+string (REGEX REPLACE ".*#define +NN_VERSION_AGE +([0-9]+).*" "\\1" NN_VERSION_AGE "${NN_HDR_STR}")
+
+if ((NN_VERSION_CURRENT STREQUAL "") OR (NN_VERSION_REVISION STREQUAL "") OR (NN_VERSION_AGE STREQUAL ""))
+    message (FATAL_ERROR "Could not read ABI version from nn.h")
 else ()
-    message (FATAL_ERROR "ERROR: CMake build system is intended only to generate MSVC solution files.\nUse autotools build system for any other purpose." )
+    set (NN_ABI_VERSION "${NN_VERSION_CURRENT}.${NN_VERSION_REVISION}.${NN_VERSION_AGE}")
+    message (STATUS "Detected nanomsg ABI v${NN_ABI_VERSION}")
 endif ()
 
-#  Build the library itself.
+# Determine package version.
+find_package (Git QUIET)
+if (DEFINED ENV{TRAVIS_TAG})
+    set (NN_PACKAGE_VERSION "$ENV{TRAVIS_TAG}")
+elseif (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
+    # Working off a git repo, using git versioning
+
+    # Get version from last tag
+    execute_process (
+        COMMAND             "${GIT_EXECUTABLE}" describe --always# | sed -e "s:v::"
+        WORKING_DIRECTORY   "${PROJECT_SOURCE_DIR}"
+        OUTPUT_VARIABLE     NN_PACKAGE_VERSION
+        OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    # If the sources have been changed locally, add -dirty to the version.
+    execute_process (
+        COMMAND             "${GIT_EXECUTABLE}" diff --quiet
+        WORKING_DIRECTORY   "${PROJECT_SOURCE_DIR}"
+        RESULT_VARIABLE     res)
+    if (res EQUAL 1)
+        set (NN_PACKAGE_VERSION "${NN_PACKAGE_VERSION}-dirty")
+    endif()
+
+elseif (EXISTS .version)
+    #  If git is not available (e.g. when building from source package)
+    #  we can extract the package version from .version file.
+    file (READ .version NN_PACKAGE_VERSION)
+else ()
+    set (NN_PACKAGE_VERSION "Unknown")
+endif()
+
+# User-defined options.
+
+option (NN_ENABLE_NANOCAT "Enable building nanocat utility." ON)
+option (NN_STATIC_LIB "Build static library instead of shared library." OFF)
+option (NN_ENABLE_GETADDRINFO_A "Enable/disable use of getaddrinfo_a in place of getaddrinfo." ON)
+
+#  Platform checks.
+
+find_package (Threads REQUIRED)
+
+if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+    add_definitions (-DNN_HAVE_LINUX)
+elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    add_definitions (-DNN_HAVE_OSX)
+elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
+    SET (NN_HAVE_WINSOCK 1)
+    add_definitions (-DNN_HAVE_WINDOWS)
+    add_definitions (-D_CRT_SECURE_NO_WARNINGS)
+elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+    add_definitions (-DNN_HAVE_FREEBSD)
+elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+    add_definitions (-DNN_HAVE_NETBSD)
+elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
+    add_definitions (-DNN_HAVE_OPENBSD)
+elseif (CMAKE_SYSTEM_NAME MATCHES "Solaris|SunOS")
+    add_definitions (-DNN_HAVE_SOLARIS)
+elseif (CMAKE_SYSTEM_NAME MATCHES "QNX")
+    add_definitions (-DNN_HAVE_QNX)
+else ()
+    message (AUTHOR_WARNING "WARNING: This platform may or may not be supported: ${CMAKE_SYSTEM_NAME}")
+    message (AUTHOR_WARNING "${ISSUE_REPORT_MSG}")
+endif ()
+
+macro (nn_check_func SYM DEF)
+    check_function_exists (${SYM} ${DEF})
+     if (${DEF})
+         add_definitions (-D${DEF}=1)
+     endif ()
+endmacro (nn_check_func)
+
+macro (nn_check_sym SYM HDR DEF)
+    check_symbol_exists (${SYM} ${HDR} ${DEF})
+     if (${DEF})
+         add_definitions (-D${DEF}=1)
+     endif ()
+endmacro (nn_check_sym)
+
+macro (nn_check_lib LIB SYM DEF)
+    check_library_exists (${LIB} ${SYM} "" ${DEF})
+    if (${DEF})
+        add_definitions (-D${DEF}=1)
+        set(NN_REQUIRED_LIBRARIES ${NN_REQUIRED_LIBRARIES} ${LIB})
+    endif ()
+endmacro (nn_check_lib)
+
+macro (nn_check_struct_member STR MEM HDR DEF)
+    check_struct_has_member ("struct ${STR}" ${MEM} ${HDR} ${DEF})
+    if (${DEF})
+        add_definitions (-D${DEF}=1)
+    endif ()
+endmacro (nn_check_struct_member)
+
+# Unconditionally declare the following feature test macros.  These are
+# needed for some platforms (glibc and SunOS/illumos) and should be harmless
+# on the others.
+add_definitions (-D_GNU_SOURCE)
+add_definitions (-D_REENTRANT)
+add_definitions (-D_THREAD_SAFE)
+add_definitions (-D_POSIX_PTHREAD_SEMANTICS)
+
+nn_check_func (gethrtime NN_HAVE_GETHRTIME)
+nn_check_func (socketpair NN_HAVE_SOCKETPAIR)
+nn_check_func (eventfd NN_HAVE_EVENTFD)
+nn_check_func (pipe NN_HAVE_PIPE)
+nn_check_func (pipe2 NN_HAVE_PIPE2)
+nn_check_func (accept4 NN_HAVE_ACCEPT4)
+nn_check_func (epoll_create NN_HAVE_EPOLL)
+nn_check_func (kqueue NN_HAVE_KQUEUE)
+nn_check_func (poll NN_HAVE_POLL)
+
+nn_check_lib (anl getaddrinfo_a NN_HAVE_GETADDRINFO_A)
+nn_check_lib (rt clock_gettime  NN_HAVE_CLOCK_GETTIME)
+nn_check_lib (rt sem_wait NN_HAVE_SEMAPHORE_RT)
+nn_check_lib (pthread sem_wait  NN_HAVE_SEMAPHORE_PTHREAD)
+
+nn_check_lib (nsl gethostbyname NN_HAVE_LIBNSL)
+nn_check_lib (socket socket NN_HAVE_LIBSOCKET)
+nn_check_sym (CLOCK_MONOTONIC time.h NN_HAVE_CLOCK_MONOTONIC)
+nn_check_sym (atomic_cas_32 atomic.h NN_HAVE_ATOMIC_SOLARIS)
+
+nn_check_struct_member(msghdr msg_control sys/socket.h NN_HAVE_MSG_CONTROL)
+
+if (NN_HAVE_SEMAPHORE_RT OR NN_HAVE_SEMAPHORE_PTHREAD)
+    add_definitions (-DNN_HAVE_SEMAPHORE)
+endif ()
+
+if (NOT NN_ENABLE_GETADDRINFO_A)
+    add_definitions (-DNN_DISABLE_GETADDRINFO_A)
+endif ()
+
+check_c_source_compiles ("
+    #include <stdint.h>
+    int main()
+    {
+        volatile uint32_t n = 0;
+        __sync_fetch_and_add (&n, 1);
+        __sync_fetch_and_sub (&n, 1);
+        return 0;
+    }
+" NN_HAVE_GCC_ATOMIC_BUILTINS)
+if (NN_HAVE_GCC_ATOMIC_BUILTINS)
+    add_definitions (-DNN_HAVE_GCC_ATOMIC_BUILTINS)
+endif ()
 
 add_subdirectory (src)
 
 #  Build the tools
 
-add_executable (nanocat tools/nanocat.c tools/options.c)
-target_link_libraries (nanocat nanomsg)
+if (NN_ENABLE_NANOCAT)
+    add_executable (nanocat tools/nanocat.c tools/options.c)
+    target_link_libraries (nanocat ${PROJECT_NAME})
+endif ()
 
 #  Build unit tests.
 
@@ -59,7 +210,7 @@
 macro (add_libnanomsg_test NAME TIMEOUT)
     list (APPEND all_tests ${NAME})
     add_executable (${NAME} tests/${NAME}.c)
-    target_link_libraries (${NAME} nanomsg)
+    target_link_libraries (${NAME} ${PROJECT_NAME})
     add_test (NAME ${NAME} COMMAND ${NAME})
     set_tests_properties (${NAME} PROPERTIES TIMEOUT ${TIMEOUT})
 endmacro (add_libnanomsg_test)
@@ -71,7 +222,7 @@
 add_libnanomsg_test (ipc_shutdown 30)
 add_libnanomsg_test (ipc_stress 5)
 add_libnanomsg_test (tcp 5)
-add_libnanomsg_test (tcp_shutdown 120)
+add_libnanomsg_test (tcp_shutdown 30)
 add_libnanomsg_test (ws 5)
 
 #  Protocol tests.
@@ -83,7 +234,7 @@
 add_libnanomsg_test (bus 5)
 
 #  Feature tests.
-add_libnanomsg_test (async_shutdown 5)
+add_libnanomsg_test (async_shutdown 30)
 add_libnanomsg_test (block 5)
 add_libnanomsg_test (term 5)
 add_libnanomsg_test (timeo 5)
@@ -95,7 +246,7 @@
 add_libnanomsg_test (device4 5)
 add_libnanomsg_test (device5 5)
 add_libnanomsg_test (device6 5)
-add_libnanomsg_test (device7 120)
+add_libnanomsg_test (device7 30)
 add_libnanomsg_test (emfile 5)
 add_libnanomsg_test (domain 5)
 add_libnanomsg_test (trie 5)
@@ -108,13 +259,17 @@
 add_libnanomsg_test (shutdown 5)
 add_libnanomsg_test (cmsg 5)
 add_libnanomsg_test (bug328 5)
-add_libnanomsg_test (win_sec_attr 5)
+
+# Platform-specific tests
+if (WIN32)
+    add_libnanomsg_test (win_sec_attr 5)
+endif()
 
 #  Build the performance tests.
 
 macro (add_libnanomsg_perf NAME)
     add_executable (${NAME} perf/${NAME}.c)
-    target_link_libraries (${NAME} nanomsg)
+    target_link_libraries (${NAME} ${PROJECT_NAME})
 endmacro (add_libnanomsg_perf)
 
 add_libnanomsg_perf (inproc_lat)
@@ -138,8 +293,10 @@
 install (FILES src/survey.h DESTINATION include/nanomsg)
 install (FILES src/bus.h DESTINATION include/nanomsg)
 
-install (TARGETS nanocat RUNTIME DESTINATION bin)
+if (BUILD_NANOCAT)
+    install (TARGETS nanocat RUNTIME DESTINATION bin)
+endif()
 
 set (CPACK_GENERATOR "NSIS")
-set (CPACK_PACKAGE_NAME "nanomsg")
+set (CPACK_PACKAGE_NAME ${PROJECT_NAME})
 include (CPack)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 146ef7d..c1fc2ca 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,7 @@
 #
 #   Copyright (c) 2012-2013 Martin Sustrik  All rights reserved.
 #   Copyright (c) 2013 GoPivotal, Inc.  All rights reserved.
+#   Copyright (c) 2015-2016 Jack R. Dunaway. All rights reserved.
 #
 #   Permission is hereby granted, free of charge, to any person obtaining a copy
 #   of this software and associated documentation files (the "Software"),
@@ -21,10 +22,6 @@
 #   IN THE SOFTWARE.
 #
 
-set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
-set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
-set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
-
 set (NN_SOURCES
     nn.h
     inproc.h
@@ -54,14 +51,6 @@
     aio/ctx.c
     aio/fsm.h
     aio/fsm.c
-    aio/poller.h
-    aio/poller.c
-    aio/poller_epoll.h
-    aio/poller_epoll.inc
-    aio/poller_kqueue.h
-    aio/poller_kqueue.inc
-    aio/poller_poll.h
-    aio/poller_poll.inc
     aio/pool.h
     aio/pool.c
     aio/timer.h
@@ -70,16 +59,8 @@
     aio/timerset.c
     aio/usock.h
     aio/usock.c
-    aio/usock_posix.h
-    aio/usock_posix.inc
-    aio/usock_win.h
-    aio/usock_win.inc
     aio/worker.h
     aio/worker.c
-    aio/worker_posix.h
-    aio/worker_posix.inc
-    aio/worker_win.h
-    aio/worker_win.inc
 
     utils/alloc.h
     utils/alloc.c
@@ -97,14 +78,6 @@
     utils/cont.h
     utils/efd.h
     utils/efd.c
-    utils/efd_eventfd.h
-    utils/efd_eventfd.inc
-    utils/efd_pipe.h
-    utils/efd_pipe.inc
-    utils/efd_socketpair.h
-    utils/efd_socketpair.inc
-    utils/efd_win.h
-    utils/efd_win.inc
     utils/err.h
     utils/err.c
     utils/fast.h
@@ -129,10 +102,6 @@
     utils/sleep.c
     utils/thread.h
     utils/thread.c
-    utils/thread_posix.h
-    utils/thread_posix.inc
-    utils/thread_win.h
-    utils/thread_win.inc
     utils/wire.h
     utils/wire.c
 
@@ -271,20 +240,139 @@
 )
 
 if (WIN32)
-    LIST (APPEND NN_SOURCES
+    list (APPEND NN_SOURCES
+        aio/usock_win.h
+        aio/usock_win.inc
+        aio/worker_win.h
+        aio/worker_win.inc
+        utils/thread_win.h
+        utils/thread_win.inc
         utils/win.h
     )
+elseif (UNIX)
+    list (APPEND NN_SOURCES
+        aio/usock_posix.h
+        aio/usock_posix.inc
+        aio/worker_posix.h
+        aio/worker_posix.inc
+        utils/thread_posix.h
+        utils/thread_posix.inc
+    )
+else ()
+    message (FATAL_ERROR "Assertion failed; this path is unreachable.")
 endif ()
 
-add_library (nanomsg SHARED ${NN_SOURCES})
+if (NN_HAVE_EPOLL)
+    add_definitions (-DNN_USE_EPOLL)
+    list (APPEND NN_SOURCES
+        aio/poller.h
+        aio/poller.c
+        aio/poller_epoll.h
+        aio/poller_epoll.inc
+    )
+elseif (NN_HAVE_KQUEUE)
+    add_definitions (-DNN_USE_KQUEUE)
+    list (APPEND NN_SOURCES
+        aio/poller.h
+        aio/poller.c
+        aio/poller_kqueue.h
+        aio/poller_kqueue.inc
+    )
+elseif (NN_HAVE_POLL)
+    add_definitions (-DNN_USE_POLL)
+    list (APPEND NN_SOURCES
+        aio/poller.h
+        aio/poller.c
+        aio/poller_poll.h
+        aio/poller_poll.inc
+    )
+elseif (NN_HAVE_WINSOCK)
+    # No operation
+else ()
+    message (SEND_ERROR "ERROR: could not determine socket polling method.")
+    message (SEND_ERROR "${ISSUE_REPORT_MSG}" )
+endif ()
 
-add_definitions (-DNN_EXPORTS)
+if (NN_HAVE_EVENTFD)
+    add_definitions (-DNN_USE_EVENTFD)
+    list (APPEND NN_SOURCES
+        utils/efd_eventfd.h
+        utils/efd_eventfd.inc
+    )
+elseif (NN_HAVE_PIPE)
+    add_definitions (-DNN_USE_PIPE)
+    list (APPEND NN_SOURCES
+        utils/efd_pipe.h
+        utils/efd_pipe.inc
+    )
+elseif (NN_HAVE_SOCKETPAIR)
+    add_definitions (-DNN_USE_SOCKETPAIR)
+    list (APPEND NN_SOURCES
+        utils/efd_socketpair.h
+        utils/efd_socketpair.inc
+    )
+elseif (NN_HAVE_WINSOCK)
+    add_definitions (-DNN_USE_WINSOCK)
+    list (APPEND NN_SOURCES
+        utils/efd_win.h
+        utils/efd_win.inc
+    )
+else ()
+    message (SEND_ERROR "ERROR: could not determine socket signaling method.")
+    message (SEND_ERROR "${ISSUE_REPORT_MSG}" )
+endif ()
 
-target_link_libraries (nanomsg ws2_32)
-target_link_libraries (nanomsg mswsock)
-target_link_libraries (nanomsg advapi32)
+# Provide same folder structure in IDE as on disk
+foreach (f ${NN_SOURCES})
+    # Get the path of the file relative to source directory
+    if (IS_ABSOLUTE "${f}")
+        file (RELATIVE_PATH f ${CMAKE_CURRENT_SOURCE_DIR} ${f})
+    endif ()
+    set (SRC_GROUP "${f}")
+    set (f "${CMAKE_CURRENT_SOURCE_DIR}/${f}")
 
-install(TARGETS nanomsg
+    # Remove the filename part
+    string (REGEX REPLACE "(.*)(/[^/]*)$" "\\1" SRC_GROUP ${SRC_GROUP})
+
+    # CMake source_group expects \\, not /
+    string (REPLACE / \\ SRC_GROUP ${SRC_GROUP})
+    source_group ("${SRC_GROUP}" FILES ${f})
+endforeach ()
+
+if (NN_STATIC_LIB)
+    add_library (${PROJECT_NAME} STATIC ${NN_SOURCES})
+    add_definitions (-DNN_STATIC_LIB)
+else ()
+    add_library (${PROJECT_NAME} SHARED ${NN_SOURCES})
+    add_definitions (-DNN_SHARED_LIB)
+    set_target_properties (${PROJECT_NAME} PROPERTIES
+        VERSION "${NN_PACKAGE_VERSION}"
+        SOVERSION "${NN_ABI_VERSION}")
+endif ()
+
+# Set library outputs same as top-level project binary outputs
+set_target_properties (${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
+set_target_properties (${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
+set_target_properties (${PROJECT_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
+
+target_link_libraries (${PROJECT_NAME} ${NN_REQUIRED_LIBRARIES})
+if (WIN32)
+    target_link_libraries (${PROJECT_NAME} ws2_32)
+    target_link_libraries (${PROJECT_NAME} mswsock)
+    target_link_libraries (${PROJECT_NAME} advapi32)
+elseif (UNIX)
+    if(THREADS_HAVE_PTHREAD_ARG)
+        add_definitions (-pthread)
+    endif()
+    if(CMAKE_THREAD_LIBS_INIT)
+        target_link_libraries (${PROJECT_NAME} "${CMAKE_THREAD_LIBS_INIT}")
+    endif()
+else ()
+    message (FATAL_ERROR "Assertion failed; this path is unreachable.")
+endif ()
+
+install (TARGETS ${PROJECT_NAME}
     ARCHIVE DESTINATION lib
     LIBRARY DESTINATION lib
-    RUNTIME DESTINATION bin)
+    RUNTIME DESTINATION bin
+)
diff --git a/src/aio/poller.c b/src/aio/poller.c
index 86c54b4..4e911f2 100644
--- a/src/aio/poller.c
+++ b/src/aio/poller.c
@@ -1,5 +1,6 @@
 /*
     Copyright (c) 2012 Martin Sustrik  All rights reserved.
+    Copyright (c) 2015-2016 Jack R. Dunaway.  All rights reserved.
 
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"),
@@ -22,14 +23,12 @@
 
 #include "poller.h"
 
-#if !defined NN_HAVE_WINDOWS
-
-#if defined NN_USE_POLL
-#include "poller_poll.inc"
-#elif defined NN_USE_EPOLL
-#include "poller_epoll.inc"
+#if defined NN_USE_EPOLL
+    #include "poller_epoll.inc"
 #elif defined NN_USE_KQUEUE
-#include "poller_kqueue.inc"
-#endif
-
+    #include "poller_kqueue.inc"
+#elif defined NN_USE_POLL
+    #include "poller_poll.inc"
+#else
+    #error
 #endif
diff --git a/src/aio/poller.h b/src/aio/poller.h
index 890f137..bcb8f95 100644
--- a/src/aio/poller.h
+++ b/src/aio/poller.h
@@ -1,5 +1,6 @@
 /*
     Copyright (c) 2012-2013 Martin Sustrik  All rights reserved.
+    Copyright (c) 2015-2016 Jack R. Dunaway.  All rights reserved.
 
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"),
@@ -23,18 +24,18 @@
 #ifndef NN_POLLER_INCLUDED
 #define NN_POLLER_INCLUDED
 
-#if !defined NN_HAVE_WINDOWS
-
 #define NN_POLLER_IN 1
 #define NN_POLLER_OUT 2
 #define NN_POLLER_ERR 3
 
-#if defined NN_USE_POLL
-#include "poller_poll.h"
-#elif defined NN_USE_EPOLL
-#include "poller_epoll.h"
+#if defined NN_USE_EPOLL
+    #include "poller_epoll.h"
 #elif defined NN_USE_KQUEUE
-#include "poller_kqueue.h"
+    #include "poller_kqueue.h"
+#elif defined NN_USE_POLL
+    #include "poller_poll.h"
+#else
+    #error
 #endif
 
 int nn_poller_init (struct nn_poller *self);
@@ -51,6 +52,3 @@
     struct nn_poller_hndl **hndl);
 
 #endif
-
-#endif
-
diff --git a/src/nn.h b/src/nn.h
index c52c3b3..031dbd6 100644
--- a/src/nn.h
+++ b/src/nn.h
@@ -1,7 +1,8 @@
 /*
     Copyright (c) 2012-2014 Martin Sustrik  All rights reserved.
     Copyright (c) 2013 GoPivotal, Inc.  All rights reserved.
-    Copyright 2016 Garrett D'Amore <garrett@damore.org>
+    Copyright 2015-2016 Garrett D'Amore <garrett@damore.org>
+    Copyright (c) 2015-2016 Jack R. Dunaway.  All rights reserved.
 
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"),
@@ -33,12 +34,14 @@
 #include <stddef.h>
 #include <stdint.h>
 
-/*  Handle DSO symbol visibility                                             */
+/*  Handle DSO symbol visibility. */
 #if defined NN_NO_EXPORTS
 #   define NN_EXPORT
 #else
 #   if defined _WIN32
-#      if defined NN_EXPORTS
+#      if defined NN_STATIC_LIB
+#          define NN_EXPORT extern
+#      elif defined NN_SHARED_LIB
 #          define NN_EXPORT __declspec(dllexport)
 #      else
 #          define NN_EXPORT __declspec(dllimport)
diff --git a/src/utils/efd.c b/src/utils/efd.c
index e9baa28..b01f179 100644
--- a/src/utils/efd.c
+++ b/src/utils/efd.c
@@ -1,6 +1,7 @@
 /*
     Copyright (c) 2012-2013 Martin Sustrik  All rights reserved.
     Copyright 2015 Garrett D'Amore <garrett@damore.org>
+    Copyright (c) 2015-2016 Jack R. Dunaway.  All rights reserved.
 
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"),
@@ -23,16 +24,16 @@
 
 #include "efd.h"
 
-#if defined NN_HAVE_WINDOWS
-#include "efd_win.inc"
-#elif defined NN_HAVE_EVENTFD
-#include "efd_eventfd.inc"
-#elif defined NN_HAVE_PIPE
-#include "efd_pipe.inc"
-#elif defined NN_HAVE_SOCKETPAIR
-#include "efd_socketpair.inc"
+#if defined NN_USE_EVENTFD
+    #include "efd_eventfd.inc"
+#elif defined NN_USE_PIPE
+    #include "efd_pipe.inc"
+#elif defined NN_USE_SOCKETPAIR
+    #include "efd_socketpair.inc"
+#elif defined NN_USE_WINSOCK
+    #include "efd_win.inc"
 #else
-#error
+    #error
 #endif
 
 #if defined NN_HAVE_POLL
@@ -78,7 +79,7 @@
     if (nn_slow (rc == SOCKET_ERROR)) {
         rc = nn_err_wsa_to_posix (WSAGetLastError ());
         errno = rc;
-        
+
         /*  Treat these as a non-fatal errors, typically occuring when the
             socket is being closed from a separate thread during a blocking
             I/O operation. */
@@ -94,5 +95,5 @@
 }
 
 #else
-#error
+    #error
 #endif
diff --git a/src/utils/efd.h b/src/utils/efd.h
index f87cfd7..2e5f52d 100644
--- a/src/utils/efd.h
+++ b/src/utils/efd.h
@@ -1,6 +1,7 @@
 /*
     Copyright (c) 2012-2013 Martin Sustrik  All rights reserved.
     Copyright 2015 Garrett D'Amore <garrett@damore.org>
+    Copyright (c) 2015-2016 Jack R. Dunaway.  All rights reserved.
 
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"),
@@ -30,16 +31,16 @@
 
 #include "fd.h"
 
-#if defined NN_HAVE_WINDOWS
-#include "efd_win.h"
-#elif defined NN_HAVE_EVENTFD
-#include "efd_eventfd.h"
-#elif defined NN_HAVE_PIPE
-#include "efd_pipe.h"
-#elif defined NN_HAVE_SOCKETPAIR
-#include "efd_socketpair.h"
+#if defined NN_USE_EVENTFD
+    #include "efd_eventfd.h"
+#elif defined NN_USE_PIPE
+    #include "efd_pipe.h"
+#elif defined NN_USE_SOCKETPAIR
+    #include "efd_socketpair.h"
+#elif defined NN_USE_WINSOCK
+    #include "efd_win.h"
 #else
-#error
+    #error
 #endif
 
 /*  Initialise the efd object. */
@@ -67,4 +68,3 @@
 int nn_efd_wait (struct nn_efd *self, int timeout);
 
 #endif
-