noderb 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +19 -0
- data/README.md +25 -0
- data/ext/noderb_extension/extconf.rb +11 -0
- data/ext/noderb_extension/libuv/AUTHORS +11 -0
- data/ext/noderb_extension/libuv/LICENSE +48 -0
- data/ext/noderb_extension/libuv/Makefile +119 -0
- data/ext/noderb_extension/libuv/README +45 -0
- data/ext/noderb_extension/libuv/build/all.gyp +254 -0
- data/ext/noderb_extension/libuv/build/common.gypi +13 -0
- data/ext/noderb_extension/libuv/build/gyp_uv +43 -0
- data/ext/noderb_extension/libuv/config-mingw.mk +67 -0
- data/ext/noderb_extension/libuv/config-unix.mk +121 -0
- data/ext/noderb_extension/libuv/create-msvs-files.bat +14 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ANNOUNCE +482 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/BUGS +141 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/Bmakefile +268 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/CONTRIBUTORS +140 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/COPYING +150 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/COPYING.LIB +504 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ChangeLog +5194 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/FAQ +451 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/GNUmakefile +593 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/MAINTAINERS +4 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/Makefile +516 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/NEWS +1245 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/Nmakefile +24 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/Nmakefile.tests +260 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/PROGRESS +4 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/README +601 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/README.Borland +57 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/README.CV +3036 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/README.NONPORTABLE +783 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/README.Watcom +62 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/README.WinCE +6 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/TODO +7 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/WinCE-PORT +222 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/attr.c +53 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/autostatic.c +69 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/barrier.c +47 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/build/all.gyp +207 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/builddmc.bat +9 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/cancel.c +44 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/cleanup.c +148 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/condvar.c +50 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/config.h +153 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/context.h +74 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/create.c +308 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/dll.c +92 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/errno.c +94 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/exit.c +44 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/fork.c +39 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/global.c +107 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/implement.h +944 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/misc.c +50 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/mutex.c +62 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/need_errno.h +145 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/nonportable.c +47 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/private.c +54 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.c +66 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.dsp +142 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.dsw +29 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread.h +1368 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_destroy.c +79 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getdetachstate.c +86 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getinheritsched.c +51 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getschedparam.c +52 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getschedpolicy.c +61 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getscope.c +54 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getstackaddr.c +97 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_getstacksize.c +100 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_init.c +117 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setdetachstate.c +91 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setinheritsched.c +57 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setschedparam.c +63 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setschedpolicy.c +55 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setscope.c +62 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setstackaddr.c +97 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_attr_setstacksize.c +110 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_destroy.c +103 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_init.c +69 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrier_wait.c +104 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_destroy.c +83 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_getpshared.c +95 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_init.c +85 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_barrierattr_setpshared.c +119 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cancel.c +189 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_destroy.c +253 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_init.c +167 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_signal.c +231 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_cond_wait.c +567 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_destroy.c +86 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_getpshared.c +97 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_init.c +87 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_condattr_setpshared.c +117 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_delay_np.c +172 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_detach.c +136 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_equal.c +76 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_exit.c +106 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getconcurrency.c +45 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getschedparam.c +75 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getspecific.c +87 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getunique_np.c +47 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_getw32threadhandle_np.c +65 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_join.c +157 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_key_create.c +108 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_key_delete.c +125 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_kill.c +105 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_consistent.c +187 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_destroy.c +148 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_init.c +130 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_lock.c +269 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_timedlock.c +324 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_trylock.c +154 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutex_unlock.c +175 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_destroy.c +83 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getkind_np.c +44 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getpshared.c +95 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_getrobust.c +113 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_gettype.c +56 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_init.c +86 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setkind_np.c +44 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setpshared.c +119 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_setrobust.c +119 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_mutexattr_settype.c +143 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_num_processors_np.c +56 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_once.c +79 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_destroy.c +143 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_init.c +109 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_rdlock.c +102 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_timedrdlock.c +109 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_timedwrlock.c +139 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_tryrdlock.c +102 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_trywrlock.c +122 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_unlock.c +93 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlock_wrlock.c +133 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_destroy.c +84 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_getpshared.c +97 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_init.c +83 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_rwlockattr_setpshared.c +120 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_self.c +141 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setcancelstate.c +125 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setcanceltype.c +126 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setconcurrency.c +53 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setschedparam.c +123 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_setspecific.c +167 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_destroy.c +111 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_init.c +123 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_lock.c +80 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_trylock.c +77 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_spin_unlock.c +71 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_testcancel.c +103 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_timechange_handler_np.c +108 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/pthread_win32_attach_detach_np.c +258 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_MCS_lock.c +278 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_callUserDestroyRoutines.c +232 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_calloc.c +56 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_cond_check_need_init.c +78 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_getprocessors.c +91 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_is_attr.c +47 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_mutex_check_need_init.c +92 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_new.c +94 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_processInitialize.c +92 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_processTerminate.c +105 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_relmillisecs.c +132 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_reuse.c +151 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_rwlock_cancelwrwait.c +50 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_rwlock_check_need_init.c +77 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_semwait.c +135 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_spinlock_check_need_init.c +78 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_threadDestroy.c +79 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_threadStart.c +357 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_throw.c +189 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_timespec.c +83 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_tkAssocCreate.c +118 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/ptw32_tkAssocDestroy.c +114 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/rwlock.c +51 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched.c +53 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched.h +183 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched_get_priority_max.c +134 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched_get_priority_min.c +135 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched_getscheduler.c +71 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched_setscheduler.c +83 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sched_yield.c +71 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_close.c +58 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_destroy.c +144 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_getvalue.c +110 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_init.c +169 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_open.c +58 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_post.c +128 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_post_multiple.c +142 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_timedwait.c +238 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_trywait.c +117 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_unlink.c +58 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sem_wait.c +187 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/semaphore.c +69 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/semaphore.h +169 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/signal.c +179 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/spin.c +46 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/sync.c +43 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/tsd.c +44 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/version.rc +388 -0
- data/ext/noderb_extension/libuv/deps/pthread-win32/w32_CancelableWait.c +161 -0
- data/ext/noderb_extension/libuv/doc/desired-api.md +159 -0
- data/ext/noderb_extension/libuv/doc/iocp-links.html +574 -0
- data/ext/noderb_extension/libuv/include/ares.h +582 -0
- data/ext/noderb_extension/libuv/include/ares_version.h +24 -0
- data/ext/noderb_extension/libuv/include/eio.h +376 -0
- data/ext/noderb_extension/libuv/include/ev.h +835 -0
- data/ext/noderb_extension/libuv/include/ngx-queue.h +102 -0
- data/ext/noderb_extension/libuv/include/tree.h +762 -0
- data/ext/noderb_extension/libuv/include/uv-unix.h +138 -0
- data/ext/noderb_extension/libuv/include/uv-win.h +187 -0
- data/ext/noderb_extension/libuv/include/uv.h +635 -0
- data/ext/noderb_extension/libuv/src/ares/AUTHORS +37 -0
- data/ext/noderb_extension/libuv/src/ares/CHANGES +1198 -0
- data/ext/noderb_extension/libuv/src/ares/CMakeLists.txt +22 -0
- data/ext/noderb_extension/libuv/src/ares/NEWS +21 -0
- data/ext/noderb_extension/libuv/src/ares/README +60 -0
- data/ext/noderb_extension/libuv/src/ares/README.cares +13 -0
- data/ext/noderb_extension/libuv/src/ares/README.msvc +118 -0
- data/ext/noderb_extension/libuv/src/ares/README.node +21 -0
- data/ext/noderb_extension/libuv/src/ares/RELEASE-NOTES +25 -0
- data/ext/noderb_extension/libuv/src/ares/TODO +23 -0
- data/ext/noderb_extension/libuv/src/ares/ares__close_sockets.c +66 -0
- data/ext/noderb_extension/libuv/src/ares/ares__get_hostent.c +263 -0
- data/ext/noderb_extension/libuv/src/ares/ares__read_line.c +71 -0
- data/ext/noderb_extension/libuv/src/ares/ares__timeval.c +111 -0
- data/ext/noderb_extension/libuv/src/ares/ares_cancel.c +63 -0
- data/ext/noderb_extension/libuv/src/ares/ares_data.c +190 -0
- data/ext/noderb_extension/libuv/src/ares/ares_data.h +65 -0
- data/ext/noderb_extension/libuv/src/ares/ares_destroy.c +105 -0
- data/ext/noderb_extension/libuv/src/ares/ares_dns.h +90 -0
- data/ext/noderb_extension/libuv/src/ares/ares_expand_name.c +193 -0
- data/ext/noderb_extension/libuv/src/ares/ares_expand_string.c +75 -0
- data/ext/noderb_extension/libuv/src/ares/ares_fds.c +62 -0
- data/ext/noderb_extension/libuv/src/ares/ares_free_hostent.c +39 -0
- data/ext/noderb_extension/libuv/src/ares/ares_free_string.c +25 -0
- data/ext/noderb_extension/libuv/src/ares/ares_gethostbyaddr.c +292 -0
- data/ext/noderb_extension/libuv/src/ares/ares_gethostbyname.c +515 -0
- data/ext/noderb_extension/libuv/src/ares/ares_getnameinfo.c +426 -0
- data/ext/noderb_extension/libuv/src/ares/ares_getopt.c +122 -0
- data/ext/noderb_extension/libuv/src/ares/ares_getopt.h +53 -0
- data/ext/noderb_extension/libuv/src/ares/ares_getsock.c +72 -0
- data/ext/noderb_extension/libuv/src/ares/ares_init.c +1665 -0
- data/ext/noderb_extension/libuv/src/ares/ares_ipv6.h +78 -0
- data/ext/noderb_extension/libuv/src/ares/ares_library_init.c +132 -0
- data/ext/noderb_extension/libuv/src/ares/ares_library_init.h +39 -0
- data/ext/noderb_extension/libuv/src/ares/ares_llist.c +86 -0
- data/ext/noderb_extension/libuv/src/ares/ares_llist.h +42 -0
- data/ext/noderb_extension/libuv/src/ares/ares_mkquery.c +195 -0
- data/ext/noderb_extension/libuv/src/ares/ares_nowarn.c +59 -0
- data/ext/noderb_extension/libuv/src/ares/ares_nowarn.h +24 -0
- data/ext/noderb_extension/libuv/src/ares/ares_options.c +253 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_a_reply.c +260 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_aaaa_reply.c +256 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_mx_reply.c +170 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_ns_reply.c +182 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_ptr_reply.c +208 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_srv_reply.c +179 -0
- data/ext/noderb_extension/libuv/src/ares/ares_parse_txt_reply.c +201 -0
- data/ext/noderb_extension/libuv/src/ares/ares_private.h +351 -0
- data/ext/noderb_extension/libuv/src/ares/ares_process.c +1296 -0
- data/ext/noderb_extension/libuv/src/ares/ares_query.c +183 -0
- data/ext/noderb_extension/libuv/src/ares/ares_rules.h +144 -0
- data/ext/noderb_extension/libuv/src/ares/ares_search.c +322 -0
- data/ext/noderb_extension/libuv/src/ares/ares_send.c +134 -0
- data/ext/noderb_extension/libuv/src/ares/ares_setup.h +191 -0
- data/ext/noderb_extension/libuv/src/ares/ares_strcasecmp.c +66 -0
- data/ext/noderb_extension/libuv/src/ares/ares_strcasecmp.h +30 -0
- data/ext/noderb_extension/libuv/src/ares/ares_strdup.c +42 -0
- data/ext/noderb_extension/libuv/src/ares/ares_strdup.h +26 -0
- data/ext/noderb_extension/libuv/src/ares/ares_strerror.c +56 -0
- data/ext/noderb_extension/libuv/src/ares/ares_timeout.c +80 -0
- data/ext/noderb_extension/libuv/src/ares/ares_version.c +11 -0
- data/ext/noderb_extension/libuv/src/ares/ares_writev.c +79 -0
- data/ext/noderb_extension/libuv/src/ares/ares_writev.h +36 -0
- data/ext/noderb_extension/libuv/src/ares/bitncmp.c +59 -0
- data/ext/noderb_extension/libuv/src/ares/bitncmp.h +26 -0
- data/ext/noderb_extension/libuv/src/ares/config_cygwin/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/ares/config_darwin/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/ares/config_freebsd/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/ares/config_linux/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/ares/config_openbsd/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/ares/config_sunos/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/ares/config_win32/ares_config.h +369 -0
- data/ext/noderb_extension/libuv/src/ares/get_ver.awk +35 -0
- data/ext/noderb_extension/libuv/src/ares/inet_net_pton.c +450 -0
- data/ext/noderb_extension/libuv/src/ares/inet_net_pton.h +31 -0
- data/ext/noderb_extension/libuv/src/ares/inet_ntop.c +232 -0
- data/ext/noderb_extension/libuv/src/ares/inet_ntop.h +27 -0
- data/ext/noderb_extension/libuv/src/ares/nameser.h +193 -0
- data/ext/noderb_extension/libuv/src/ares/setup_once.h +488 -0
- data/ext/noderb_extension/libuv/src/ares/windows_port.c +22 -0
- data/ext/noderb_extension/libuv/src/eio/Changes +63 -0
- data/ext/noderb_extension/libuv/src/eio/LICENSE +36 -0
- data/ext/noderb_extension/libuv/src/eio/Makefile.am +15 -0
- data/ext/noderb_extension/libuv/src/eio/aclocal.m4 +8957 -0
- data/ext/noderb_extension/libuv/src/eio/autogen.sh +3 -0
- data/ext/noderb_extension/libuv/src/eio/config.h.in +86 -0
- data/ext/noderb_extension/libuv/src/eio/config_cygwin.h +77 -0
- data/ext/noderb_extension/libuv/src/eio/config_darwin.h +137 -0
- data/ext/noderb_extension/libuv/src/eio/config_freebsd.h +78 -0
- data/ext/noderb_extension/libuv/src/eio/config_linux.h +101 -0
- data/ext/noderb_extension/libuv/src/eio/config_sunos.h +81 -0
- data/ext/noderb_extension/libuv/src/eio/configure.ac +22 -0
- data/ext/noderb_extension/libuv/src/eio/demo.c +194 -0
- data/ext/noderb_extension/libuv/src/eio/ecb.h +370 -0
- data/ext/noderb_extension/libuv/src/eio/eio.3 +3428 -0
- data/ext/noderb_extension/libuv/src/eio/eio.c +2562 -0
- data/ext/noderb_extension/libuv/src/eio/eio.pod +969 -0
- data/ext/noderb_extension/libuv/src/eio/libeio.m4 +195 -0
- data/ext/noderb_extension/libuv/src/eio/xthread.h +164 -0
- data/ext/noderb_extension/libuv/src/ev/Changes +388 -0
- data/ext/noderb_extension/libuv/src/ev/LICENSE +36 -0
- data/ext/noderb_extension/libuv/src/ev/Makefile.am +18 -0
- data/ext/noderb_extension/libuv/src/ev/Makefile.in +771 -0
- data/ext/noderb_extension/libuv/src/ev/README +58 -0
- data/ext/noderb_extension/libuv/src/ev/aclocal.m4 +8957 -0
- data/ext/noderb_extension/libuv/src/ev/autogen.sh +6 -0
- data/ext/noderb_extension/libuv/src/ev/config.guess +1526 -0
- data/ext/noderb_extension/libuv/src/ev/config.h.in +125 -0
- data/ext/noderb_extension/libuv/src/ev/config.sub +1658 -0
- data/ext/noderb_extension/libuv/src/ev/config_cygwin.h +123 -0
- data/ext/noderb_extension/libuv/src/ev/config_darwin.h +122 -0
- data/ext/noderb_extension/libuv/src/ev/config_freebsd.h +120 -0
- data/ext/noderb_extension/libuv/src/ev/config_linux.h +130 -0
- data/ext/noderb_extension/libuv/src/ev/config_sunos.h +122 -0
- data/ext/noderb_extension/libuv/src/ev/configure +13037 -0
- data/ext/noderb_extension/libuv/src/ev/configure.ac +18 -0
- data/ext/noderb_extension/libuv/src/ev/depcomp +630 -0
- data/ext/noderb_extension/libuv/src/ev/ev++.h +816 -0
- data/ext/noderb_extension/libuv/src/ev/ev.3 +5311 -0
- data/ext/noderb_extension/libuv/src/ev/ev.c +3913 -0
- data/ext/noderb_extension/libuv/src/ev/ev.pod +5243 -0
- data/ext/noderb_extension/libuv/src/ev/ev_epoll.c +266 -0
- data/ext/noderb_extension/libuv/src/ev/ev_kqueue.c +198 -0
- data/ext/noderb_extension/libuv/src/ev/ev_poll.c +148 -0
- data/ext/noderb_extension/libuv/src/ev/ev_port.c +179 -0
- data/ext/noderb_extension/libuv/src/ev/ev_select.c +310 -0
- data/ext/noderb_extension/libuv/src/ev/ev_vars.h +203 -0
- data/ext/noderb_extension/libuv/src/ev/ev_win32.c +153 -0
- data/ext/noderb_extension/libuv/src/ev/ev_wrap.h +196 -0
- data/ext/noderb_extension/libuv/src/ev/event.c +402 -0
- data/ext/noderb_extension/libuv/src/ev/event.h +170 -0
- data/ext/noderb_extension/libuv/src/ev/install-sh +294 -0
- data/ext/noderb_extension/libuv/src/ev/libev.m4 +39 -0
- data/ext/noderb_extension/libuv/src/ev/ltmain.sh +8413 -0
- data/ext/noderb_extension/libuv/src/ev/missing +336 -0
- data/ext/noderb_extension/libuv/src/ev/mkinstalldirs +111 -0
- data/ext/noderb_extension/libuv/src/uv-common.c +172 -0
- data/ext/noderb_extension/libuv/src/uv-common.h +53 -0
- data/ext/noderb_extension/libuv/src/uv-cygwin.c +52 -0
- data/ext/noderb_extension/libuv/src/uv-darwin.c +64 -0
- data/ext/noderb_extension/libuv/src/uv-eio.c +113 -0
- data/ext/noderb_extension/libuv/src/uv-eio.h +13 -0
- data/ext/noderb_extension/libuv/src/uv-freebsd.c +65 -0
- data/ext/noderb_extension/libuv/src/uv-linux.c +51 -0
- data/ext/noderb_extension/libuv/src/uv-sunos.c +60 -0
- data/ext/noderb_extension/libuv/src/uv-unix.c +2408 -0
- data/ext/noderb_extension/libuv/src/win/async.c +129 -0
- data/ext/noderb_extension/libuv/src/win/cares.c +304 -0
- data/ext/noderb_extension/libuv/src/win/core.c +155 -0
- data/ext/noderb_extension/libuv/src/win/error.c +140 -0
- data/ext/noderb_extension/libuv/src/win/getaddrinfo.c +341 -0
- data/ext/noderb_extension/libuv/src/win/handle.c +176 -0
- data/ext/noderb_extension/libuv/src/win/internal.h +237 -0
- data/ext/noderb_extension/libuv/src/win/loop-watcher.c +128 -0
- data/ext/noderb_extension/libuv/src/win/pipe.c +828 -0
- data/ext/noderb_extension/libuv/src/win/process.c +936 -0
- data/ext/noderb_extension/libuv/src/win/req.c +141 -0
- data/ext/noderb_extension/libuv/src/win/stdio.c +75 -0
- data/ext/noderb_extension/libuv/src/win/stream.c +149 -0
- data/ext/noderb_extension/libuv/src/win/tcp.c +895 -0
- data/ext/noderb_extension/libuv/src/win/timer.c +269 -0
- data/ext/noderb_extension/libuv/src/win/util.c +82 -0
- data/ext/noderb_extension/libuv/test/benchmark-ares.c +117 -0
- data/ext/noderb_extension/libuv/test/benchmark-getaddrinfo.c +90 -0
- data/ext/noderb_extension/libuv/test/benchmark-list.h +77 -0
- data/ext/noderb_extension/libuv/test/benchmark-ping-pongs.c +210 -0
- data/ext/noderb_extension/libuv/test/benchmark-pound.c +237 -0
- data/ext/noderb_extension/libuv/test/benchmark-pump.c +459 -0
- data/ext/noderb_extension/libuv/test/benchmark-sizes.c +39 -0
- data/ext/noderb_extension/libuv/test/benchmark-spawn.c +154 -0
- data/ext/noderb_extension/libuv/test/dns-server.c +323 -0
- data/ext/noderb_extension/libuv/test/echo-server.c +299 -0
- data/ext/noderb_extension/libuv/test/run-benchmarks.c +64 -0
- data/ext/noderb_extension/libuv/test/run-tests.c +82 -0
- data/ext/noderb_extension/libuv/test/runner-unix.c +335 -0
- data/ext/noderb_extension/libuv/test/runner-unix.h +36 -0
- data/ext/noderb_extension/libuv/test/runner-win.c +343 -0
- data/ext/noderb_extension/libuv/test/runner-win.h +42 -0
- data/ext/noderb_extension/libuv/test/runner.c +311 -0
- data/ext/noderb_extension/libuv/test/runner.h +155 -0
- data/ext/noderb_extension/libuv/test/task.h +111 -0
- data/ext/noderb_extension/libuv/test/test-async.c +218 -0
- data/ext/noderb_extension/libuv/test/test-callback-stack.c +205 -0
- data/ext/noderb_extension/libuv/test/test-connection-fail.c +149 -0
- data/ext/noderb_extension/libuv/test/test-delayed-accept.c +198 -0
- data/ext/noderb_extension/libuv/test/test-fail-always.c +29 -0
- data/ext/noderb_extension/libuv/test/test-get-currentexe.c +53 -0
- data/ext/noderb_extension/libuv/test/test-getaddrinfo.c +110 -0
- data/ext/noderb_extension/libuv/test/test-gethostbyname.c +192 -0
- data/ext/noderb_extension/libuv/test/test-getsockname.c +196 -0
- data/ext/noderb_extension/libuv/test/test-hrtime.c +51 -0
- data/ext/noderb_extension/libuv/test/test-idle.c +83 -0
- data/ext/noderb_extension/libuv/test/test-list.h +165 -0
- data/ext/noderb_extension/libuv/test/test-loop-handles.c +361 -0
- data/ext/noderb_extension/libuv/test/test-pass-always.c +28 -0
- data/ext/noderb_extension/libuv/test/test-ping-pong.c +256 -0
- data/ext/noderb_extension/libuv/test/test-pipe-bind-error.c +148 -0
- data/ext/noderb_extension/libuv/test/test-ref.c +91 -0
- data/ext/noderb_extension/libuv/test/test-shutdown-eof.c +183 -0
- data/ext/noderb_extension/libuv/test/test-spawn.c +345 -0
- data/ext/noderb_extension/libuv/test/test-tcp-bind-error.c +204 -0
- data/ext/noderb_extension/libuv/test/test-tcp-bind6-error.c +164 -0
- data/ext/noderb_extension/libuv/test/test-tcp-writealot.c +198 -0
- data/ext/noderb_extension/libuv/test/test-timer-again.c +141 -0
- data/ext/noderb_extension/libuv/test/test-timer.c +134 -0
- data/ext/noderb_extension/noderb.c +340 -0
- data/ext/noderb_extension/noderb.h +2 -0
- data/lib/noderb/connection.rb +21 -0
- data/lib/noderb/process.rb +17 -0
- data/lib/noderb.rb +25 -0
- metadata +470 -0
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<style>
|
|
4
|
+
body {
|
|
5
|
+
max-width: 40em;
|
|
6
|
+
margin: 2em;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
a {
|
|
10
|
+
color: inherit;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
a:hover {
|
|
14
|
+
color: red;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
dt { margin-top: 1em; }
|
|
18
|
+
dd { margin-bottom: 1em; }
|
|
19
|
+
|
|
20
|
+
table {
|
|
21
|
+
margin: 1em 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
table th {
|
|
26
|
+
text-align: left;
|
|
27
|
+
padding: 0.2em;
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
table td {
|
|
32
|
+
padding: 0.2em;
|
|
33
|
+
text-align: left;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
</style>
|
|
38
|
+
<title>Asynchronous I/O in Windows for Unix Programmers</title>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<h1>Asynchronous I/O in Windows for Unix Programmers</h1>
|
|
42
|
+
|
|
43
|
+
<p>Ryan Dahl ryan@joyent.com
|
|
44
|
+
|
|
45
|
+
<p>This document assumes you are familiar with how non-blocking socket I/O
|
|
46
|
+
is done in Unix.
|
|
47
|
+
|
|
48
|
+
<p>The syscall
|
|
49
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms740141(v=VS.85).aspx"><code>select</code>
|
|
50
|
+
is available in Windows</a>
|
|
51
|
+
but <code>select</code> processing is O(n) in the number of file descriptors
|
|
52
|
+
unlike the modern constant-time multiplexers like epoll which makes select
|
|
53
|
+
unacceptable for high-concurrency servers.
|
|
54
|
+
This document will describe how high-concurrency programs are
|
|
55
|
+
designed in Windows.
|
|
56
|
+
|
|
57
|
+
<p>
|
|
58
|
+
Instead of <a href="http://en.wikipedia.org/wiki/Epoll">epoll</a>
|
|
59
|
+
or
|
|
60
|
+
<a href="http://en.wikipedia.org/wiki/Kqueue">kqueue</a>,
|
|
61
|
+
Windows has its own I/O multiplexer called
|
|
62
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx">I/O completion ports</a>
|
|
63
|
+
(IOCPs). IOCPs are the objects used to poll
|
|
64
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms686358(v=vs.85).aspx">overlapped I/O</a>
|
|
65
|
+
for completion. IOCP polling is constant time (REF?).
|
|
66
|
+
|
|
67
|
+
<p>
|
|
68
|
+
The fundamental variation is that in a Unix you generally ask the kernel to
|
|
69
|
+
wait for state change in a file descriptor's readability or writablity. With
|
|
70
|
+
overlapped I/O and IOCPs the programmers waits for asynchronous function
|
|
71
|
+
calls to complete.
|
|
72
|
+
For example, instead of waiting for a socket to become writable and then
|
|
73
|
+
using <a
|
|
74
|
+
href="http://www.kernel.org/doc/man-pages/online/pages/man2/send.2.html"><code>send(2)</code></a>
|
|
75
|
+
on it, as you commonly would do in a Unix, with overlapped I/O you
|
|
76
|
+
would rather <a
|
|
77
|
+
href="http://msdn.microsoft.com/en-us/library/ms742203(v=vs.85).aspx"><code>WSASend()</code></a>
|
|
78
|
+
the data and then wait for it to have been sent.
|
|
79
|
+
|
|
80
|
+
<p> Unix non-blocking I/O is not beautiful. A principle abstraction in Unix
|
|
81
|
+
is the unified treatment of many things as files (or more precisely as file
|
|
82
|
+
descriptors). <code>write(2)</code>, <code>read(2)</code>, and
|
|
83
|
+
<code>close(2)</code> work with TCP sockets just as they do on regular
|
|
84
|
+
files. Well—kind of. Synchronous operations work similarly on different
|
|
85
|
+
types of file descriptors but once demands on performance drive you to world of
|
|
86
|
+
<code>O_NONBLOCK</code> various types of file descriptors can act quite
|
|
87
|
+
different for even the most basic operations. In particular,
|
|
88
|
+
regular file system files do <i>not</i> support non-blocking operations.
|
|
89
|
+
|
|
90
|
+
(Disturbingly no man page mentions this rather important fact.)
|
|
91
|
+
|
|
92
|
+
For example, one cannot poll on a regular file FD for readability expecting
|
|
93
|
+
it to indicate when it is safe to do a non-blocking read.
|
|
94
|
+
|
|
95
|
+
Regular file are always readable and <code>read(2)</code> calls
|
|
96
|
+
<i>always</i> have the possibility of blocking the calling thread for an
|
|
97
|
+
unknown amount of time.
|
|
98
|
+
|
|
99
|
+
<p>POSIX has defined <a
|
|
100
|
+
href="http://pubs.opengroup.org/onlinepubs/007908799/xsh/aio.h.html">an
|
|
101
|
+
asynchronous interface</a> for some operations but implementations for
|
|
102
|
+
many Unixes have unclear status. On Linux the
|
|
103
|
+
<code>aio_*</code> routines are implemented in userland in GNU libc using
|
|
104
|
+
pthreads.
|
|
105
|
+
<a
|
|
106
|
+
href="http://www.kernel.org/doc/man-pages/online/pages/man2/io_submit.2.html"><code>io_submit(2)</code></a>
|
|
107
|
+
does not have a GNU libc wrapper and has been reported <a
|
|
108
|
+
href="http://voinici.ceata.org/~sana/blog/?p=248"> to be very slow and
|
|
109
|
+
possibly blocking</a>. <a
|
|
110
|
+
href="http://download.oracle.com/docs/cd/E19253-01/816-5171/aio-write-3rt/index.html">Solaris
|
|
111
|
+
has real kernel AIO</a> but it's unclear what its performance
|
|
112
|
+
characteristics are for socket I/O as opposed to disk I/O.
|
|
113
|
+
Contemporary high-performance Unix socket programs use non-blocking
|
|
114
|
+
file descriptors with a I/O multiplexer—not POSIX AIO.
|
|
115
|
+
Common practice for accessing the disk asynchronously is still done using custom
|
|
116
|
+
userland thread pools—not POSIX AIO.
|
|
117
|
+
|
|
118
|
+
<p>Windows IOCPs does support both sockets and regular file I/O which
|
|
119
|
+
greatly simplifies the handling of disks. For example,
|
|
120
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365468(v=VS.85).aspx"><code>ReadFileEx()</code></a>
|
|
121
|
+
operates on both.
|
|
122
|
+
As a first example let's look at how <code>ReadFile()</code> works.
|
|
123
|
+
|
|
124
|
+
<pre>
|
|
125
|
+
typedef void* HANDLE;
|
|
126
|
+
|
|
127
|
+
BOOL ReadFile(HANDLE file,
|
|
128
|
+
void* buffer,
|
|
129
|
+
DWORD numberOfBytesToRead,
|
|
130
|
+
DWORD* numberOfBytesRead,
|
|
131
|
+
OVERLAPPED* overlapped);
|
|
132
|
+
</pre>
|
|
133
|
+
|
|
134
|
+
<p>
|
|
135
|
+
The function has the possibility of executing the read synchronously
|
|
136
|
+
or asynchronously. A synchronous operation is indicated by
|
|
137
|
+
returning 0 and <a
|
|
138
|
+
href="http://msdn.microsoft.com/en-us/library/ms741580(v=VS.85).aspx">WSAGetLastError()</code></a>
|
|
139
|
+
returning <code>WSA_IO_PENDING</code>.
|
|
140
|
+
When <code>ReadFile()</code> operates asynchronously the
|
|
141
|
+
the user-supplied <a
|
|
142
|
+
href="http://msdn.microsoft.com/en-us/library/ms741665(v=VS.85).aspx"><code>OVERLAPPED*</code></a>
|
|
143
|
+
is a handle to the incomplete operation.
|
|
144
|
+
|
|
145
|
+
<pre>
|
|
146
|
+
typedef struct {
|
|
147
|
+
unsigned long* Internal;
|
|
148
|
+
unsigned long* InternalHigh;
|
|
149
|
+
union {
|
|
150
|
+
struct {
|
|
151
|
+
WORD Offset;
|
|
152
|
+
WORD OffsetHigh;
|
|
153
|
+
};
|
|
154
|
+
void* Pointer;
|
|
155
|
+
};
|
|
156
|
+
HANDLE hEvent;
|
|
157
|
+
} OVERLAPPED;
|
|
158
|
+
</pre>
|
|
159
|
+
|
|
160
|
+
To poll on the completion of one of these functions,
|
|
161
|
+
use an IOCP, <code>overlapped->hEvent</code>, and
|
|
162
|
+
<a
|
|
163
|
+
href="http://msdn.microsoft.com/en-us/library/aa364986(v=vs.85).aspx"><code>GetQueuedCompletionStatus()</code></a>.
|
|
164
|
+
|
|
165
|
+
<h3>Simple TCP Connection Example</h3>
|
|
166
|
+
|
|
167
|
+
<p>To demonstrate the use of <code>GetQueuedCompletionStatus()</code> an
|
|
168
|
+
example of connecting to <code>localhost</code> at port 8000 is presented.
|
|
169
|
+
|
|
170
|
+
<pre>
|
|
171
|
+
char* buffer[200];
|
|
172
|
+
WSABUF b = { buffer, 200 };
|
|
173
|
+
size_t bytes_recvd;
|
|
174
|
+
int r, total_events;
|
|
175
|
+
OVERLAPPED overlapped;
|
|
176
|
+
HANDLE port;
|
|
177
|
+
|
|
178
|
+
port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
|
|
179
|
+
if (!port) {
|
|
180
|
+
goto error;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
r = WSARecv(socket, &b, 1, &bytes_recvd, NULL, &overlapped, NULL);
|
|
185
|
+
|
|
186
|
+
CreateIoCompletionPort(port, &overlapped.hEvent,
|
|
187
|
+
|
|
188
|
+
if (r == 0) {
|
|
189
|
+
if (WSAGetLastError() == WSA_IO_PENDING) {
|
|
190
|
+
/* Asynchronous */
|
|
191
|
+
GetQueuedCompletionStatus()
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
if (r == WAIT_TIMEOUT) {
|
|
195
|
+
printf("Timeout\n");
|
|
196
|
+
} else {
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
} else {
|
|
202
|
+
/* Error */
|
|
203
|
+
printf("Error %d\n", WSAGetLastError());
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
/* Synchronous */
|
|
207
|
+
printf("read %ld bytes from socket\n", bytes_recvd);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
</pre>
|
|
213
|
+
|
|
214
|
+
<h3>Previous Work</h3>
|
|
215
|
+
|
|
216
|
+
<p> Writing code that can take advantage of the best worlds on across Unix operating
|
|
217
|
+
systems and Windows is very difficult, requiring one to understand intricate
|
|
218
|
+
APIs and undocumented details from many different operating systems. There
|
|
219
|
+
are several projects which have made attempts to provide an abstraction
|
|
220
|
+
layer but in the author's opinion, none are completely satisfactory.
|
|
221
|
+
|
|
222
|
+
<p><b>Marc Lehmann's
|
|
223
|
+
<a href="http://software.schmorp.de/pkg/libev.html">libev</a> and
|
|
224
|
+
<a href="http://software.schmorp.de/pkg/libeio.html">libeio</a>.</b>
|
|
225
|
+
libev is the perfect minimal abstraction of the Unix I/O multiplexers. It
|
|
226
|
+
includes several helpful tools like <code>ev_async</code>, which is for
|
|
227
|
+
asynchronous notification, but the main piece is the <code>ev_io</code>,
|
|
228
|
+
which informs the user about the state of file descriptors. As mentioned
|
|
229
|
+
before, in general it is not possible to get state changes for regular
|
|
230
|
+
files—and even if it were the <code>write(2)</code> and
|
|
231
|
+
<code>read(2)</code> calls do not guarantee that they won't block.
|
|
232
|
+
Therefore libeio is provided for calling various disk-related
|
|
233
|
+
syscalls in a managed thread pool. Unfortunately the abstraction layer
|
|
234
|
+
which libev targets is not appropriate for IOCPs—libev works strictly
|
|
235
|
+
with file descriptors and does not the concept of a <i>socket</i>.
|
|
236
|
+
Furthermore users on Unix will be using libeio for file I/O which is not
|
|
237
|
+
ideal for porting to Windows. On windows libev currently uses
|
|
238
|
+
<code>select()</code>—which is limited to 64 file descriptors per
|
|
239
|
+
thread.
|
|
240
|
+
|
|
241
|
+
<p><b><a href="http://monkey.org/~provos/libevent/">libevent</a>.</b>
|
|
242
|
+
Somewhat bulkier than libev with code for RPC, DNS, and HTTP included.
|
|
243
|
+
Does not support file I/O.
|
|
244
|
+
libev was
|
|
245
|
+
created after Lehmann <a
|
|
246
|
+
href="http://www.mail-archive.com/libevent-users@monkey.org/msg00753.html">evaluated
|
|
247
|
+
libevent and rejected it</a>—it's interesting to read his reasons
|
|
248
|
+
why. <a
|
|
249
|
+
href="http://google-opensource.blogspot.com/2010/01/libevent-20x-like-libevent-14x-only.html">A
|
|
250
|
+
major rewrite</a> was done for version 2 to support Windows IOCPs but <a
|
|
251
|
+
href="http://www.mail-archive.com/libevent-users@monkey.org/msg01730.html">anecdotal
|
|
252
|
+
evidence</a> suggests that it is still not working correctly.
|
|
253
|
+
|
|
254
|
+
<p><b><a
|
|
255
|
+
href="http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio.html">Boost
|
|
256
|
+
ASIO</a>.</b> It basically does what you want on Windows and Unix for
|
|
257
|
+
sockets. That is, epoll on Linux, kqueue on Macintosh, IOCPs on Windows.
|
|
258
|
+
It does not support file I/O. In the author's opinion is it too large
|
|
259
|
+
for a not extremely difficult problem (~300 files, ~12000 semicolons).
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
<h2>File Types</h2>
|
|
264
|
+
<p>
|
|
265
|
+
Almost every socket operation that you're familiar with has an
|
|
266
|
+
overlapped counter-part. The following section tries to pair Windows
|
|
267
|
+
overlapped I/O syscalls with non-blocking Unix ones.
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
<h3>TCP Sockets</h3>
|
|
271
|
+
|
|
272
|
+
TCP Sockets are by far the most important stream to get right.
|
|
273
|
+
Servers should expect to be handling tens of thousands of these
|
|
274
|
+
per thread, concurrently. This is possible with overlapped I/O in Windows if
|
|
275
|
+
one is careful to avoid Unix-ism like file descriptors. (Windows has a
|
|
276
|
+
hard limit of 2048 open file descriptors—see
|
|
277
|
+
<a
|
|
278
|
+
href="http://msdn.microsoft.com/en-us/library/6e3b887c.aspx"><code>_setmaxstdio()</code></a>.)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
<dl>
|
|
282
|
+
|
|
283
|
+
<dt><code>send(2)</code>, <code>write(2)</code></dt>
|
|
284
|
+
<dd>Windows:
|
|
285
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms742203(v=vs.85).aspx"><code>WSASend()</code></a>,
|
|
286
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365748(v=VS.85).aspx"><code>WriteFileEx()</code></a>
|
|
287
|
+
</dd>
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
<dt><code>recv(2)</code>, <code>read(2)</code></dt>
|
|
291
|
+
<dd>
|
|
292
|
+
Windows:
|
|
293
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms741688(v=VS.85).aspx"><code>WSARecv()</code></a>,
|
|
294
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365468(v=VS.85).aspx"><code>ReadFileEx()</code></a>
|
|
295
|
+
</dd>
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
<dt><code>connect(2)</code></dt>
|
|
299
|
+
<dd>
|
|
300
|
+
Windows: <a href="http://msdn.microsoft.com/en-us/library/ms737606(VS.85).aspx"><code>ConnectEx()</code></a>
|
|
301
|
+
|
|
302
|
+
<p>
|
|
303
|
+
Non-blocking <code>connect()</code> is has difficult semantics in
|
|
304
|
+
Unix. The proper way to connect to a remote host is this: call
|
|
305
|
+
<code>connect(2)</code> while it returns
|
|
306
|
+
<code>EINPROGRESS</code> poll on the file descriptor for writablity.
|
|
307
|
+
Then use
|
|
308
|
+
<pre>int error;
|
|
309
|
+
socklen_t len = sizeof(int);
|
|
310
|
+
getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);</pre>
|
|
311
|
+
A zero <code>error</code> indicates that the connection succeeded.
|
|
312
|
+
(Documented in <code>connect(2)</code> under <code>EINPROGRESS</code>
|
|
313
|
+
on the Linux man page.)
|
|
314
|
+
</dd>
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
<dt><code>accept(2)</code></dt>
|
|
318
|
+
<dd>
|
|
319
|
+
Windows: <a href="http://msdn.microsoft.com/en-us/library/ms737524(v=VS.85).aspx"><code>AcceptEx()</code></a>
|
|
320
|
+
</dd>
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
<dt><code>sendfile(2)</code></dt>
|
|
324
|
+
<dd>
|
|
325
|
+
Windows: <a href="http://msdn.microsoft.com/en-us/library/ms740565(v=VS.85).aspx"><code>TransmitFile()</code></a>
|
|
326
|
+
|
|
327
|
+
<p> The exact API of <code>sendfile(2)</code> on Unix has not been agreed
|
|
328
|
+
on yet. Each operating system does it slightly different. All
|
|
329
|
+
<code>sendfile(2)</code> implementations (except possibly FreeBSD?) are blocking
|
|
330
|
+
even on non-blocking sockets.
|
|
331
|
+
<ul>
|
|
332
|
+
<li><a href="http://www.kernel.org/doc/man-pages/online/pages/man2/sendfile.2.html">Linux <code>sendfile(2)</code></a>
|
|
333
|
+
<li><a href="http://www.freebsd.org/cgi/man.cgi?query=sendfile&sektion=2">FreeBSD <code>sendfile(2)</code></a>
|
|
334
|
+
<li><a href="http://www.manpagez.com/man/2/sendfile/">Darwin <code>sendfile(2)</code></a>
|
|
335
|
+
</ul>
|
|
336
|
+
Marc Lehmann has written <a
|
|
337
|
+
href="https://github.com/joyent/node/blob/2c185a9dfd3be8e718858b946333c433c375c295/deps/libeio/eio.c#L954-1080">a
|
|
338
|
+
portable version in libeio</a>.
|
|
339
|
+
</dd>
|
|
340
|
+
|
|
341
|
+
<dt><code>shutdown(2)</code>, graceful close, half-duplex connections</dt>
|
|
342
|
+
<dd>
|
|
343
|
+
<a
|
|
344
|
+
href="http://msdn.microsoft.com/en-us/library/ms738547(v=VS.85).aspx">Graceful
|
|
345
|
+
Shutdown, Linger Options, and Socket Closure</a>
|
|
346
|
+
<br/>
|
|
347
|
+
<a
|
|
348
|
+
href="http://msdn.microsoft.com/en-us/library/ms737757(VS.85).aspx"><code>DisconnectEx()</code></a>
|
|
349
|
+
|
|
350
|
+
</dd>
|
|
351
|
+
|
|
352
|
+
<dt><code>close(2)</code></dt>
|
|
353
|
+
<dd>
|
|
354
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms737582(v=VS.85).aspx"><code>closesocket()</code></a>
|
|
355
|
+
</dd>
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
The following are nearly same in Windows overlapped and Unix
|
|
359
|
+
non-blocking sockets. The only difference is that the Unix variants
|
|
360
|
+
take integer file descriptors while Windows uses <code>SOCKET</code>.
|
|
361
|
+
<ul>
|
|
362
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms740496(v=VS.85).aspx"><code>sockaddr</code></a>
|
|
363
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms737550(v=VS.85).aspx"><code>bind()</code></a>
|
|
364
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms738543(v=VS.85).aspx"><code>getsockname()</code></a>
|
|
365
|
+
</ul>
|
|
366
|
+
|
|
367
|
+
<h3>Named Pipes</h3>
|
|
368
|
+
|
|
369
|
+
Windows has "named pipes" which are more or less the same as <a
|
|
370
|
+
href="http://www.kernel.org/doc/man-pages/online/pages/man7/unix.7.html"><code>AF_Unix</code>
|
|
371
|
+
domain sockets</a>. <code>AF_Unix</code> sockets exist in the file system
|
|
372
|
+
often looking like
|
|
373
|
+
<pre>/tmp/<i>pipename</i></pre>
|
|
374
|
+
|
|
375
|
+
Windows named pipes have a path, but they are not directly part of the file
|
|
376
|
+
system; instead they look like
|
|
377
|
+
|
|
378
|
+
<pre>\\.\pipe\<i>pipename</i></pre>
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
<dl>
|
|
382
|
+
<dt><code>socket(AF_Unix, SOCK_STREAM, 0), bind(2), listen(2)</code></dt>
|
|
383
|
+
<dd>
|
|
384
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx"><code>CreateNamedPipe()</code></a>
|
|
385
|
+
|
|
386
|
+
<p>Use <code>FILE_FLAG_OVERLAPPED</code>, <code>PIPE_TYPE_BYTE</code>,
|
|
387
|
+
<code>PIPE_NOWAIT</code>.
|
|
388
|
+
</dd>
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
<dt><code>send(2)</code>, <code>write(2)</code></dt>
|
|
392
|
+
<dd>
|
|
393
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365748(v=VS.85).aspx"><code>WriteFileEx()</code></a>
|
|
394
|
+
</dd>
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
<dt><code>recv(2)</code>, <code>read(2)</code></dt>
|
|
398
|
+
<dd>
|
|
399
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365468(v=VS.85).aspx"><code>ReadFileEx()</code></a>
|
|
400
|
+
</dd>
|
|
401
|
+
|
|
402
|
+
<dt><code>connect(2)</code></dt>
|
|
403
|
+
<dd>
|
|
404
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx"><code>CreateNamedPipe()</code></a>
|
|
405
|
+
</dd>
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
<dt><code>accept(2)</code></dt>
|
|
409
|
+
<dd>
|
|
410
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365146(v=VS.85).aspx"><code>ConnectNamedPipe()</code></a>
|
|
411
|
+
</dd>
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
</dl>
|
|
415
|
+
|
|
416
|
+
Examples:
|
|
417
|
+
<ul>
|
|
418
|
+
<li><a
|
|
419
|
+
href="http://msdn.microsoft.com/en-us/library/aa365601(v=VS.85).aspx">Named
|
|
420
|
+
Pipe Server Using Completion Routines</a>
|
|
421
|
+
<li><a
|
|
422
|
+
href="http://msdn.microsoft.com/en-us/library/aa365603(v=VS.85).aspx">Named
|
|
423
|
+
Pipe Server Using Overlapped I/O</a>
|
|
424
|
+
</ul>
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
<h3>Regular Files</h3>
|
|
428
|
+
|
|
429
|
+
<p>
|
|
430
|
+
In Unix file system files are not able to use non-blocking I/O. There are
|
|
431
|
+
some operating systems that have asynchronous I/O but it is not standard and
|
|
432
|
+
at least on Linux is done with pthreads in GNU libc. For this reason
|
|
433
|
+
applications designed to be portable across different Unixes must manage a
|
|
434
|
+
thread pool for issuing file I/O syscalls.
|
|
435
|
+
|
|
436
|
+
<p>
|
|
437
|
+
The situation is better in Windows: true overlapped I/O is available when
|
|
438
|
+
reading or writing a stream of data to a file.
|
|
439
|
+
|
|
440
|
+
<dl>
|
|
441
|
+
|
|
442
|
+
<dt><code>write(2)</code></dt>
|
|
443
|
+
<dd> Windows:
|
|
444
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365748(v=VS.85).aspx"><code>WriteFileEx()</code></a>
|
|
445
|
+
|
|
446
|
+
<p>Solaris's event completion ports has true in-kernel async writes with <a
|
|
447
|
+
href="http://download.oracle.com/docs/cd/E19253-01/816-5171/aio-write-3rt/index.html">aio_write(3RT)</a>
|
|
448
|
+
</dd>
|
|
449
|
+
|
|
450
|
+
<dt><code>read(2)</code></dt>
|
|
451
|
+
<dd> Windows:
|
|
452
|
+
<a href="http://msdn.microsoft.com/en-us/library/aa365468(v=VS.85).aspx"><code>ReadFileEx()</code></a>
|
|
453
|
+
|
|
454
|
+
<p>Solaris's event completion ports has true in-kernel async reads with <a
|
|
455
|
+
href="http://download.oracle.com/docs/cd/E19253-01/816-5171/aio-read-3rt/index.html">aio_read(3RT)</a>
|
|
456
|
+
</dd>
|
|
457
|
+
|
|
458
|
+
</dl>
|
|
459
|
+
|
|
460
|
+
<h3>Console/TTY</h3>
|
|
461
|
+
|
|
462
|
+
<p>It is (usually?) possible to poll a Unix TTY file descriptor for
|
|
463
|
+
readability or writablity just like a TCP socket—this is very helpful
|
|
464
|
+
and nice. In Windows the situation is worse, not only is it a completely
|
|
465
|
+
different API but there are not overlapped versions to read and write to the
|
|
466
|
+
TTY. Polling for readability can be accomplished by waiting in another
|
|
467
|
+
thread with <a
|
|
468
|
+
href="http://msdn.microsoft.com/en-us/library/ms685061(VS.85).aspx"><code>RegisterWaitForSingleObject()</code></a>.
|
|
469
|
+
|
|
470
|
+
<dl>
|
|
471
|
+
|
|
472
|
+
<dt><code>read(2)</code></dt>
|
|
473
|
+
<dd>
|
|
474
|
+
<a
|
|
475
|
+
href="http://msdn.microsoft.com/en-us/library/ms684958(v=VS.85).aspx"><code>ReadConsole()</code></a>
|
|
476
|
+
and
|
|
477
|
+
<a
|
|
478
|
+
href="http://msdn.microsoft.com/en-us/library/ms684961(v=VS.85).aspx"><code>ReadConsoleInput()</code></a>
|
|
479
|
+
do not support overlapped I/O and there are no overlapped
|
|
480
|
+
counter-parts. One strategy to get around this is
|
|
481
|
+
<pre><a href="http://msdn.microsoft.com/en-us/library/ms685061(VS.85).aspx">RegisterWaitForSingleObject</a>(&tty_wait_handle, tty_handle,
|
|
482
|
+
tty_want_poll, NULL, INFINITE, WT_EXECUTEINWAITTHREAD |
|
|
483
|
+
WT_EXECUTEONLYONCE)</pre>
|
|
484
|
+
which will execute <code>tty_want_poll()</code> in a different thread.
|
|
485
|
+
You can use this to notify the calling thread that
|
|
486
|
+
<code>ReadConsoleInput()</code> will not block.
|
|
487
|
+
</dd>
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
<dt><code>write(2)</code></dt>
|
|
491
|
+
<dd>
|
|
492
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms687401(v=VS.85).aspx"><code>WriteConsole()</code></a>
|
|
493
|
+
is also blocking but this is probably acceptable.
|
|
494
|
+
</dd>
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
<dt><a
|
|
498
|
+
href="http://www.kernel.org/doc/man-pages/online/pages/man3/tcsetattr.3.html"><code>tcsetattr(3)</code></a></dt>
|
|
499
|
+
<dd>
|
|
500
|
+
<a href="http://msdn.microsoft.com/en-us/library/ms686033(VS.85).aspx"><code>SetConsoleMode()</code></a>
|
|
501
|
+
</dd>
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
</dl>
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
<h2>Assorted Links</h2>
|
|
509
|
+
<p>
|
|
510
|
+
tips
|
|
511
|
+
<ul>
|
|
512
|
+
<li> overlapped = non-blocking.
|
|
513
|
+
<li> There is no overlapped <a href="http://msdn.microsoft.com/en-us/library/ms738518(VS.85).aspx"><code>GetAddrInfoEx()</code></a> function. It seems Asynchronous Procedure Calls must be used instead.
|
|
514
|
+
<li> <a href=http://msdn.microsoft.com/en-us/library/ms740673(VS.85).aspx"><code>Windows Sockets 2</code></a>
|
|
515
|
+
</ul>
|
|
516
|
+
|
|
517
|
+
<p>
|
|
518
|
+
IOCP:
|
|
519
|
+
<ul>
|
|
520
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms686358(v=vs.85).aspx">Synchronization and Overlapped Input and Output</a>
|
|
521
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms741665(v=VS.85).aspx"><code>OVERLAPPED</code> Structure</a>
|
|
522
|
+
<ul>
|
|
523
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms683209(v=VS.85).aspx"><code>GetOverlappedResult()</code></a>
|
|
524
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms683244(v=VS.85).aspx"><code>HasOverlappedIoCompleted()</code></a>
|
|
525
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/aa363792(v=vs.85).aspx"><code>CancelIoEx()</code></a>
|
|
526
|
+
— cancels an overlapped operation.
|
|
527
|
+
</ul>
|
|
528
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms742203(v=vs.85).aspx"><code>WSASend()</code></a>
|
|
529
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms741688(v=VS.85).aspx"><code>WSARecv()</code></a>
|
|
530
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms737606(VS.85).aspx"><code>ConnectEx()</code></a>
|
|
531
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms740565(v=VS.85).aspx"><code>TransmitFile()</code></a>
|
|
532
|
+
— an async <code>sendfile()</code> for windows.
|
|
533
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms741565(v=VS.85).aspx"><code>WSADuplicateSocket()</code></a>
|
|
534
|
+
— describes how to share a socket between two processes.
|
|
535
|
+
<li id="setmaxstdio"><a href="http://msdn.microsoft.com/en-us/library/6e3b887c.aspx"><code>_setmaxstdio()</code></a>
|
|
536
|
+
— something like setting the maximum number of file decriptors
|
|
537
|
+
and <a
|
|
538
|
+
href="http://www.kernel.org/doc/man-pages/online/pages/man2/setrlimit.2.html"><code>setrlimit(3)</code></a>
|
|
539
|
+
AKA <code>ulimit -n</code>. Note the file descriptor limit on windows is
|
|
540
|
+
2048.
|
|
541
|
+
</ul>
|
|
542
|
+
|
|
543
|
+
<p>
|
|
544
|
+
APC:
|
|
545
|
+
<ul>
|
|
546
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms681951(v=vs.85).aspx">Asynchronous Procedure Calls</a>
|
|
547
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/ms682016"><code>DNSQuery()</code></a>
|
|
548
|
+
— General purpose DNS query function like <code>res_query()</code> on Unix.
|
|
549
|
+
</ul>
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
Pipes:
|
|
553
|
+
<ul>
|
|
554
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/aa365781(v=VS.85).aspx"><code>Pipe functions</code></a>
|
|
555
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx"><code>CreateNamedPipe</code></a>
|
|
556
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/aa365144(v=VS.85).aspx"><code>CallNamedPipe</code></a>
|
|
557
|
+
— like <code>accept</code> is for Unix pipes.
|
|
558
|
+
<li><a href="http://msdn.microsoft.com/en-us/library/aa365146(v=VS.85).aspx"><code>ConnectNamedPipe</code></a>
|
|
559
|
+
</ul>
|
|
560
|
+
|
|
561
|
+
<code>WaitForMultipleObjectsEx</code> is pronounced "wait for multiple object sex".
|
|
562
|
+
|
|
563
|
+
Also useful:
|
|
564
|
+
<a
|
|
565
|
+
href="http://msdn.microsoft.com/en-us/library/xw1ew2f8(v=vs.80).aspx">Introduction
|
|
566
|
+
to Visual C++ for Unix Users</a>
|
|
567
|
+
|
|
568
|
+
<br><br>
|
|
569
|
+
<a
|
|
570
|
+
href="http://ebookbrowse.com/network-programming-for-microsoft-windows-2nd-edition-2002-pdf-d73663829">Network
|
|
571
|
+
Programming For Microsoft Windows 2nd Edition 2002</a>. Juicy details on
|
|
572
|
+
page 119.
|
|
573
|
+
|
|
574
|
+
</body></html>
|