Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

more messing up

svn:r246
  • Loading branch information...
commit c9ad03bc0369132f436efd0af4b398d5f5e64c65 0 parents
provos authored October 28, 2006

Showing 64 changed files with 19,550 additions and 0 deletions. Show diff stats Hide diff stats

  1. 55  Makefile.am
  2. 35  README
  3. 231  WIN32-Code/config.h
  4. 91  WIN32-Code/misc.c
  5. 11  WIN32-Code/misc.h
  6. 433  WIN32-Code/win32.c
  7. 100  WIN32-Prj/event_test/event_test.dsp
  8. 180  WIN32-Prj/event_test/test.txt
  9. 128  WIN32-Prj/libevent.dsp
  10. 74  WIN32-Prj/libevent.dsw
  11. 100  WIN32-Prj/signal_test/signal_test.dsp
  12. 100  WIN32-Prj/time_test/time_test.dsp
  13. 79  acconfig.h
  14. 446  buffer.c
  15. 163  compat/sys/_time.h
  16. 488  compat/sys/queue.h
  17. 677  compat/sys/tree.h
  18. 372  configure.in
  19. 423  devpoll.c
  20. 369  epoll.c
  21. 52  epoll_sub.c
  22. 413  evbuffer.c
  23. 322  evdns.3
  24. 2,176  evdns.c
  25. 306  evdns.h
  26. 56  event-internal.h
  27. 578  event.3
  28. 865  event.c
  29. 339  event.h
  30. 1,378  event_rpcgen.py
  31. 360  event_tagging.c
  32. 128  evhttp.h
  33. 509  evport.c
  34. 37  evsignal.h
  35. 137  http-internal.h
  36. 1,632  http.c
  37. 238  install-sh
  38. 413  kqueue.c
  39. 219  log.c
  40. 43  log.h
  41. 360  missing
  42. 40  mkinstalldirs
  43. 377  poll.c
  44. 985  rtsig.c
  45. 15  sample/Makefile.am
  46. 135  sample/event-test.c
  47. 62  sample/signal-test.c
  48. 70  sample/time-test.c
  49. 376  select.c
  50. 212  signal.c
  51. 1  stamp-h.in
  52. 74  strlcpy.c
  53. 31  test/Makefile.am
  54. 181  test/bench.c
  55. 923  test/regress.c
  56. 43  test/regress.h
  57. 17  test/regress.rpc
  58. 144  test/regress_dns.c
  59. 426  test/regress_http.c
  60. 68  test/test-eof.c
  61. 27  test/test-init.c
  62. 68  test/test-time.c
  63. 68  test/test-weof.c
  64. 91  test/test.sh
55  Makefile.am
... ...
@@ -0,0 +1,55 @@
  1
+AUTOMAKE_OPTIONS = foreign no-dependencies
  2
+
  3
+
  4
+bin_SCRIPTS = event_rpcgen.py
  5
+
  6
+EXTRA_DIST = acconfig.h event.h event-internal.h log.h evsignal.h evdns.3 \
  7
+	event.3 \
  8
+	kqueue.c epoll_sub.c epoll.c select.c rtsig.c poll.c signal.c \
  9
+	evport.c devpoll.c event_rpcgen.py \
  10
+	sample/Makefile.am sample/Makefile.in sample/event-test.c \
  11
+	sample/signal-test.c sample/time-test.c \
  12
+	test/Makefile.am test/Makefile.in test/bench.c test/regress.c \
  13
+	test/test-eof.c test/test-weof.c test/test-time.c \
  14
+	test/test-init.c test/test.sh \
  15
+	compat/sys/queue.h compat/sys/tree.h compat/sys/_time.h \
  16
+	WIN32-Code/config.h WIN32-Code/misc.c \
  17
+	WIN32-Code/win32.c WIN32-Code/misc.h \
  18
+	WIN32-Prj/event_test/event_test.dsp \
  19
+	WIN32-Prj/event_test/test.txt WIN32-Prj/libevent.dsp \
  20
+	WIN32-Prj/libevent.dsw WIN32-Prj/signal_test/signal_test.dsp \
  21
+	WIN32-Prj/time_test/time_test.dsp
  22
+
  23
+lib_LTLIBRARIES = libevent.la
  24
+
  25
+if BUILD_WIN32
  26
+
  27
+SUBDIRS = . sample
  28
+SYS_LIBS = -lws2_32
  29
+SYS_SRC = WIN32-Code/misc.c WIN32-Code/win32.c
  30
+SYS_INCLUDES = -IWIN32-Code
  31
+
  32
+else
  33
+
  34
+SUBDIRS = . sample test
  35
+SYS_LIBS =
  36
+SYS_SRC =
  37
+SYS_INCLUDES =
  38
+
  39
+endif
  40
+
  41
+libevent_la_SOURCES = event.c buffer.c evbuffer.c log.c event_tagging.c \
  42
+	 http.c evhttp.h http-internal.h evdns.c evdns.h $(SYS_SRC)
  43
+libevent_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS)
  44
+libevent_la_LDFLAGS = -release @VERSION@ -version-info 1:3:0
  45
+
  46
+include_HEADERS = event.h evhttp.h evdns.h
  47
+
  48
+INCLUDES = -Icompat $(SYS_INCLUDES)
  49
+
  50
+man_MANS = event.3 evdns.3
  51
+
  52
+verify: libevent.la
  53
+	cd $(srcdir)/test && make verify	
  54
+
  55
+DISTCLEANFILES = *~
35  README
... ...
@@ -0,0 +1,35 @@
  1
+To build libevent, type
  2
+
  3
+$ ./configure && make
  4
+
  5
+Install as root via
  6
+
  7
+# make install
  8
+
  9
+You can run the regression tests by
  10
+
  11
+$ make verify
  12
+
  13
+Before, reporting any problems, please run the regression tests.
  14
+
  15
+To enable the low-level tracing build the library as:
  16
+
  17
+CFLAGS=-DUSE_DEBUG ./configure [...]
  18
+ 
  19
+Acknowledgements:
  20
+-----------------
  21
+
  22
+The following people have helped with suggestions, ideas, code or
  23
+fixing bugs:
  24
+
  25
+  Nick Mathewson
  26
+  Andrew Danforth
  27
+  Shie Erlich
  28
+  Mike Davis
  29
+  William Ahern
  30
+  Alexander von Gernler
  31
+  Artur Grabowski
  32
+  Stas Bekman
  33
+  Tassilo von Parseval
  34
+
  35
+If I have forgotten your name, please contact me.
231  WIN32-Code/config.h
... ...
@@ -0,0 +1,231 @@
  1
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
  2
+/* Define if kqueue works correctly with pipes */
  3
+#undef HAVE_WORKING_KQUEUE
  4
+
  5
+/* Define to `unsigned long long' if <sys/types.h> doesn't define.  */
  6
+#undef u_int64_t
  7
+
  8
+/* Define to `unsigned int' if <sys/types.h> doesn't define.  */
  9
+#undef u_int32_t
  10
+
  11
+/* Define to `unsigned short' if <sys/types.h> doesn't define.  */
  12
+#undef u_int16_t
  13
+
  14
+/* Define to `unsigned char' if <sys/types.h> doesn't define.  */
  15
+#undef u_int8_t
  16
+
  17
+/* Define if timeradd is defined in <sys/time.h> */
  18
+#undef HAVE_TIMERADD
  19
+#ifndef HAVE_TIMERADD
  20
+#undef timersub
  21
+#define timeradd(tvp, uvp, vvp)						\
  22
+	do {								\
  23
+		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
  24
+		(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;       \
  25
+		if ((vvp)->tv_usec >= 1000000) {			\
  26
+			(vvp)->tv_sec++;				\
  27
+			(vvp)->tv_usec -= 1000000;			\
  28
+		}							\
  29
+	} while (0)
  30
+#define	timersub(tvp, uvp, vvp)						\
  31
+	do {								\
  32
+		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
  33
+		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
  34
+		if ((vvp)->tv_usec < 0) {				\
  35
+			(vvp)->tv_sec--;				\
  36
+			(vvp)->tv_usec += 1000000;			\
  37
+		}							\
  38
+	} while (0)
  39
+#endif /* !HAVE_TIMERADD */
  40
+
  41
+#undef HAVE_TIMERCLEAR
  42
+#ifndef HAVE_TIMERCLEAR
  43
+#define	timerclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
  44
+#endif
  45
+
  46
+#define HAVE_TIMERCMP
  47
+#ifndef HAVE_TIMERCMP
  48
+#undef timercmp
  49
+#define	timercmp(tvp, uvp, cmp)						\
  50
+	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
  51
+	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
  52
+	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
  53
+#endif
  54
+
  55
+#undef HAVE_TIMERISSET
  56
+#ifndef HAVE_TIMERISSET
  57
+#undef timerisset
  58
+#define	timerisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
  59
+#endif
  60
+
  61
+/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
  62
+#define HAVE_TAILQFOREACH
  63
+#ifndef HAVE_TAILQFOREACH
  64
+#define	TAILQ_FIRST(head)		((head)->tqh_first)
  65
+#define	TAILQ_END(head)			NULL
  66
+#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
  67
+#define TAILQ_FOREACH(var, head, field)					\
  68
+	for((var) = TAILQ_FIRST(head);					\
  69
+	    (var) != TAILQ_END(head);					\
  70
+	    (var) = TAILQ_NEXT(var, field))
  71
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
  72
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
  73
+	(elm)->field.tqe_next = (listelm);				\
  74
+	*(listelm)->field.tqe_prev = (elm);				\
  75
+	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
  76
+} while (0)
  77
+#endif /* TAILQ_FOREACH */
  78
+
  79
+/* Define if /dev/poll is available */
  80
+#undef HAVE_DEVPOLL
  81
+
  82
+/* Define if your system supports the epoll system calls */
  83
+#undef HAVE_EPOLL
  84
+
  85
+/* Define if you have the `epoll_ctl' function. */
  86
+#undef HAVE_EPOLL_CTL
  87
+
  88
+/* Define if you have the `err' function. */
  89
+#undef HAVE_ERR
  90
+
  91
+/* Define if you have the `fcntl' function. */
  92
+#undef HAVE_FCNTL
  93
+
  94
+/* Define if you have the <fcntl.h> header file. */
  95
+#undef HAVE_FCNTL_H
  96
+
  97
+/* Define if you have the `gettimeofday' function. */
  98
+#define HAVE_GETTIMEOFDAY 1
  99
+
  100
+/* Define if you have the <inttypes.h> header file. */
  101
+#define HAVE_INTTYPES_H 1
  102
+
  103
+/* Define if you have the `kqueue' function. */
  104
+#undef HAVE_KQUEUE
  105
+
  106
+/* Define if you have the `socket' library (-lsocket). */
  107
+#undef HAVE_LIBSOCKET
  108
+
  109
+/* Define if you have the <memory.h> header file. */
  110
+#define HAVE_MEMORY_H 1
  111
+
  112
+/* Define if you have the `poll' function. */
  113
+#undef HAVE_POLL
  114
+
  115
+/* Define if you have the <poll.h> header file. */
  116
+#undef HAVE_POLL_H
  117
+
  118
+/* Define if your system supports POSIX realtime signals */
  119
+#undef HAVE_RTSIG
  120
+
  121
+/* Define if you have the `select' function. */
  122
+#undef HAVE_SELECT
  123
+
  124
+/* Define if F_SETFD is defined in <fcntl.h> */
  125
+#undef HAVE_SETFD
  126
+
  127
+/* Define if you have the <signal.h> header file. */
  128
+#undef HAVE_SIGNAL_H
  129
+
  130
+/* Define if you have the `sigtimedwait' function. */
  131
+#undef HAVE_SIGTIMEDWAIT
  132
+
  133
+/* Define if you have the <stdarg.h> header file. */
  134
+#define HAVE_STDARG_H 1
  135
+
  136
+/* Define if you have the <stdint.h> header file. */
  137
+#undef HAVE_STDINT_H
  138
+
  139
+/* Define if you have the <stdlib.h> header file. */
  140
+#define HAVE_STDLIB_H 1
  141
+
  142
+/* Define if you have the <strings.h> header file. */
  143
+#undef HAVE_STRINGS_H
  144
+
  145
+/* Define if you have the <string.h> header file. */
  146
+#define HAVE_STRING_H 1
  147
+
  148
+/* Define if you have the <sys/devpoll.h> header file. */
  149
+#undef HAVE_SYS_DEVPOLL_H
  150
+
  151
+/* Define if you have the <sys/epoll.h> header file. */
  152
+#undef HAVE_SYS_EPOLL_H
  153
+
  154
+/* Define if you have the <sys/event.h> header file. */
  155
+#undef HAVE_SYS_EVENT_H
  156
+
  157
+/* Define if you have the <sys/ioctl.h> header file. */
  158
+#undef HAVE_SYS_IOCTL_H
  159
+
  160
+/* Define if you have the <sys/queue.h> header file. */
  161
+#undef HAVE_SYS_QUEUE_H
  162
+
  163
+/* Define if you have the <sys/stat.h> header file. */
  164
+#define HAVE_SYS_STAT_H 1
  165
+
  166
+/* Define if you have the <sys/time.h> header file. */
  167
+#undef HAVE_SYS_TIME_H
  168
+
  169
+/* Define if you have the <sys/types.h> header file. */
  170
+#define HAVE_SYS_TYPES_H 1
  171
+
  172
+/* Define if TAILQ_FOREACH is defined in <sys/queue.h> */
  173
+#undef HAVE_TAILQFOREACH
  174
+
  175
+/* Define if timeradd is defined in <sys/time.h> */
  176
+#undef HAVE_TIMERADD
  177
+
  178
+/* Define if you have the <unistd.h> header file. */
  179
+#undef HAVE_UNISTD_H
  180
+
  181
+/* Define if you have the `vasprintf' function. */
  182
+#undef HAVE_VASPRINTF
  183
+
  184
+/* Define if kqueue works correctly with pipes */
  185
+#undef HAVE_WORKING_KQUEUE
  186
+
  187
+/* Define if realtime signals work on pipes */
  188
+#undef HAVE_WORKING_RTSIG
  189
+
  190
+/* Name of package */
  191
+#define PACKAGE "libevent"
  192
+
  193
+/* Define if you have the ANSI C header files. */
  194
+#undef STDC_HEADERS
  195
+
  196
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
  197
+#undef TIME_WITH_SYS_TIME
  198
+
  199
+/* Version number of package */
  200
+#define VERSION "1.0b"
  201
+
  202
+/* Define to empty if `const' does not conform to ANSI C. */
  203
+#undef const
  204
+
  205
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
  206
+   if it is not supported. */
  207
+#define inline __inline
  208
+
  209
+/* Define to `int' if <sys/types.h> does not define. */
  210
+#undef pid_t
  211
+
  212
+/* Define to `unsigned' if <sys/types.h> does not define. */
  213
+#undef size_t
  214
+
  215
+/* Define to unsigned int if you dont have it */
  216
+#undef socklen_t
  217
+
  218
+/* Define to `unsigned short' if <sys/types.h> does not define. */
  219
+#undef u_int16_t
  220
+
  221
+/* Define to `unsigned int' if <sys/types.h> does not define. */
  222
+#undef u_int32_t
  223
+
  224
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
  225
+/* #undef u_int64_t */
  226
+
  227
+/* Define to `unsigned char' if <sys/types.h> does not define. */
  228
+/* #undef u_int8_t */
  229
+
  230
+/* Define to __FUNCTION__ or __file__ if your compiler doesn't have __func__ */
  231
+#define __func__ __FUNCTION__
91  WIN32-Code/misc.c
... ...
@@ -0,0 +1,91 @@
  1
+#include <stdio.h>
  2
+#include <string.h>
  3
+#include <windows.h>
  4
+#include <sys/timeb.h>
  5
+#include <time.h>
  6
+
  7
+#ifdef __GNUC__
  8
+/*our prototypes for timeval and timezone are in here, just in case the above
  9
+  headers don't have them*/
  10
+#include "misc.h"
  11
+#endif
  12
+
  13
+/****************************************************************************
  14
+ *
  15
+ * Function: gettimeofday(struct timeval *, struct timezone *)
  16
+ *
  17
+ * Purpose:  Get current time of day.
  18
+ *
  19
+ * Arguments: tv => Place to store the curent time of day.
  20
+ *            tz => Ignored.
  21
+ *
  22
+ * Returns: 0 => Success.
  23
+ *
  24
+ ****************************************************************************/
  25
+
  26
+#ifndef HAVE_GETTIMEOFDAY
  27
+int gettimeofday(struct timeval *tv, struct timezone *tz) {
  28
+  struct _timeb tb;
  29
+
  30
+	if(tv == NULL)
  31
+		return -1;
  32
+
  33
+	_ftime(&tb);
  34
+	tv->tv_sec = tb.time;
  35
+	tv->tv_usec = ((int) tb.millitm) * 1000;
  36
+	return 0;
  37
+}
  38
+#endif
  39
+
  40
+int
  41
+win_read(int fd, void *buf, unsigned int length)
  42
+{
  43
+	DWORD dwBytesRead;
  44
+	int res = ReadFile((HANDLE) fd, buf, length, &dwBytesRead, NULL);
  45
+	if (res == 0) {
  46
+		DWORD error = GetLastError();
  47
+		if (error == ERROR_NO_DATA)
  48
+			return (0);
  49
+		return (-1);
  50
+	} else
  51
+		return (dwBytesRead);
  52
+}
  53
+
  54
+int
  55
+win_write(int fd, void *buf, unsigned int length)
  56
+{
  57
+	DWORD dwBytesWritten;
  58
+	int res = WriteFile((HANDLE) fd, buf, length, &dwBytesWritten, NULL);
  59
+	if (res == 0) {
  60
+		DWORD error = GetLastError();
  61
+		if (error == ERROR_NO_DATA)
  62
+			return (0);
  63
+		return (-1);
  64
+	} else
  65
+		return (dwBytesWritten);
  66
+}
  67
+
  68
+int
  69
+socketpair(int d, int type, int protocol, int *sv)
  70
+{
  71
+	static int count;
  72
+	char buf[64];
  73
+	HANDLE fd;
  74
+	DWORD dwMode;
  75
+	sprintf(buf, "\\\\.\\pipe\\levent-%d", count++);
  76
+	/* Create a duplex pipe which will behave like a socket pair */
  77
+	fd = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT, 
  78
+		PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, NULL);
  79
+	if (fd == INVALID_HANDLE_VALUE)
  80
+		return (-1);
  81
+	sv[0] = (int)fd;
  82
+
  83
+	fd = CreateFile(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  84
+	if (fd == INVALID_HANDLE_VALUE)
  85
+		return (-1);
  86
+	dwMode = PIPE_NOWAIT;
  87
+	SetNamedPipeHandleState(fd, &dwMode, NULL, NULL);
  88
+	sv[1] = (int)fd;
  89
+
  90
+	return (0);
  91
+}
11  WIN32-Code/misc.h
... ...
@@ -0,0 +1,11 @@
  1
+#ifndef MISC_H
  2
+#define MISC_H
  3
+
  4
+struct timezone;
  5
+struct timeval;
  6
+
  7
+#ifndef HAVE_GETTIMEOFDAY
  8
+int gettimeofday(struct timeval *,struct timezone *);
  9
+#endif
  10
+
  11
+#endif
433  WIN32-Code/win32.c
... ...
@@ -0,0 +1,433 @@
  1
+/*
  2
+ * Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
  3
+ * Copyright 2003 Michael A. Davis <mike@datanerds.net>
  4
+ * All rights reserved.
  5
+ *
  6
+ * Redistribution and use in source and binary forms, with or without
  7
+ * modification, are permitted provided that the following conditions
  8
+ * are met:
  9
+ * 1. Redistributions of source code must retain the above copyright
  10
+ *    notice, this list of conditions and the following disclaimer.
  11
+ * 2. Redistributions in binary form must reproduce the above copyright
  12
+ *    notice, this list of conditions and the following disclaimer in the
  13
+ *    documentation and/or other materials provided with the distribution.
  14
+ * 3. The name of the author may not be used to endorse or promote products
  15
+ *    derived from this software without specific prior written permission.
  16
+ *
  17
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27
+ */
  28
+#include "config.h"
  29
+
  30
+#include <winsock2.h>
  31
+
  32
+#include <windows.h>
  33
+#include <sys/types.h>
  34
+#include <sys/queue.h>
  35
+#include <sys/tree.h>
  36
+#include <signal.h>
  37
+#include <stdio.h>
  38
+#include <stdlib.h>
  39
+#include <string.h>
  40
+#include <errno.h>
  41
+#include <assert.h>
  42
+
  43
+#include "log.h"
  44
+#include "event.h"
  45
+#include "event-internal.h"
  46
+
  47
+#define XFREE(ptr) do { if (ptr) free(ptr); } while(0)
  48
+
  49
+extern struct event_list timequeue;
  50
+extern struct event_list addqueue;
  51
+extern struct event_list signalqueue;
  52
+
  53
+struct win_fd_set {
  54
+	u_int fd_count;
  55
+	SOCKET fd_array[1];
  56
+};
  57
+
  58
+int evsigcaught[NSIG];
  59
+volatile sig_atomic_t signal_caught = 0;
  60
+/* MSDN says this is required to handle SIGFPE */
  61
+volatile double SIGFPE_REQ = 0.0f;
  62
+
  63
+static void signal_handler(int sig);
  64
+
  65
+void signal_process(void);
  66
+int signal_recalc(void);
  67
+
  68
+struct win32op {
  69
+	int fd_setsz;
  70
+	struct win_fd_set *readset_in;
  71
+	struct win_fd_set *writeset_in;
  72
+	struct win_fd_set *readset_out;
  73
+	struct win_fd_set *writeset_out;
  74
+	struct win_fd_set *exset_out;
  75
+	int n_events;
  76
+	int n_events_alloc;
  77
+	struct event **events;
  78
+};
  79
+
  80
+void *win32_init	(void);
  81
+int win32_insert	(void *, struct event *);
  82
+int win32_del	(void *, struct event *);
  83
+int win32_recalc	(struct event_base *base, void *, int);
  84
+int win32_dispatch	(struct event_base *base, void *, struct timeval *);
  85
+void win32_dealloc	(void *);
  86
+
  87
+struct eventop win32ops = {
  88
+	"win32",
  89
+	win32_init,
  90
+	win32_insert,
  91
+	win32_del,
  92
+	win32_recalc,
  93
+	win32_dispatch,
  94
+	win32_dealloc
  95
+};
  96
+
  97
+#define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET)))
  98
+
  99
+static int
  100
+realloc_fd_sets(struct win32op *op, size_t new_size)
  101
+{
  102
+	size_t size;
  103
+
  104
+	assert(new_size >= op->readset_in->fd_count &&
  105
+	       new_size >= op->writeset_in->fd_count);
  106
+	assert(new_size >= 1);
  107
+
  108
+	size = FD_SET_ALLOC_SIZE(new_size);
  109
+	if (!(op->readset_in = realloc(op->readset_in, size)))
  110
+		return (-1);
  111
+	if (!(op->writeset_in = realloc(op->writeset_in, size)))
  112
+		return (-1);
  113
+	if (!(op->readset_out = realloc(op->readset_out, size)))
  114
+		return (-1);
  115
+	if (!(op->exset_out = realloc(op->exset_out, size)))
  116
+		return (-1);
  117
+	if (!(op->writeset_out = realloc(op->writeset_out, size)))
  118
+		return (-1);
  119
+	op->fd_setsz = new_size;
  120
+	return (0);
  121
+}
  122
+
  123
+static int
  124
+timeval_to_ms(struct timeval *tv)
  125
+{
  126
+	return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000));
  127
+}
  128
+
  129
+static int
  130
+do_fd_set(struct win32op *op, SOCKET s, int read)
  131
+{
  132
+	unsigned int i;
  133
+	struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
  134
+	for (i=0;i<set->fd_count;++i) {
  135
+		if (set->fd_array[i]==s)
  136
+			return (0);
  137
+	}
  138
+	if (set->fd_count == op->fd_setsz) {
  139
+		if (realloc_fd_sets(op, op->fd_setsz*2))
  140
+			return (-1);
  141
+		/* set pointer will have changed and needs reiniting! */
  142
+		set = read ? op->readset_in : op->writeset_in;
  143
+	}
  144
+	set->fd_array[set->fd_count] = s;
  145
+	return (set->fd_count++);
  146
+}
  147
+
  148
+static int
  149
+do_fd_clear(struct win32op *op, SOCKET s, int read)
  150
+{
  151
+	unsigned int i;
  152
+	struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
  153
+	for (i=0;i<set->fd_count;++i) {
  154
+		if (set->fd_array[i]==s) {
  155
+			if (--set->fd_count != i) {
  156
+				set->fd_array[i] = set->fd_array[set->fd_count];
  157
+			}
  158
+			return (0);
  159
+		}
  160
+	}
  161
+	return (0);
  162
+}
  163
+
  164
+#define NEVENT 64
  165
+void *
  166
+win32_init(void)
  167
+{
  168
+	struct win32op *winop;
  169
+	size_t size;
  170
+	if (!(winop = calloc(1, sizeof(struct win32op))))
  171
+		return NULL;
  172
+	winop->fd_setsz = NEVENT;
  173
+	size = FD_SET_ALLOC_SIZE(NEVENT);
  174
+	if (!(winop->readset_in = malloc(size)))
  175
+		goto err;
  176
+	if (!(winop->writeset_in = malloc(size)))
  177
+		goto err;
  178
+	if (!(winop->readset_out = malloc(size)))
  179
+		goto err;
  180
+	if (!(winop->writeset_out = malloc(size)))
  181
+		goto err;
  182
+	if (!(winop->exset_out = malloc(size)))
  183
+		goto err;
  184
+	winop->n_events = 0;
  185
+	winop->n_events_alloc = NEVENT;
  186
+	if (!(winop->events = malloc(NEVENT*sizeof(struct event*))))
  187
+		goto err;
  188
+	winop->readset_in->fd_count = winop->writeset_in->fd_count = 0;
  189
+	winop->readset_out->fd_count = winop->writeset_out->fd_count
  190
+		= winop->exset_out->fd_count = 0;
  191
+
  192
+	return (winop);
  193
+ err:
  194
+        XFREE(winop->readset_in);
  195
+        XFREE(winop->writeset_in);
  196
+        XFREE(winop->readset_out);
  197
+        XFREE(winop->writeset_out);
  198
+        XFREE(winop->exset_out);
  199
+        XFREE(winop->events);
  200
+        XFREE(winop);
  201
+        return (NULL);
  202
+}
  203
+
  204
+int
  205
+win32_recalc(struct event_base *base, void *arg, int max)
  206
+{
  207
+	return (signal_recalc());
  208
+}
  209
+
  210
+int
  211
+win32_insert(void *op, struct event *ev)
  212
+{
  213
+	struct win32op *win32op = op;
  214
+	int i;
  215
+
  216
+	if (ev->ev_events & EV_SIGNAL) {
  217
+		if (ev->ev_events & (EV_READ|EV_WRITE))
  218
+			event_errx(1, "%s: EV_SIGNAL incompatible use",
  219
+			           __func__);
  220
+		if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
  221
+			return (-1);
  222
+
  223
+		return (0);
  224
+	}
  225
+	if (!(ev->ev_events & (EV_READ|EV_WRITE)))
  226
+		return (0);
  227
+
  228
+	for (i=0;i<win32op->n_events;++i) {
  229
+		if(win32op->events[i] == ev) {
  230
+			event_debug(("%s: Event for %d already inserted.",
  231
+				     __func__, (int)ev->ev_fd));
  232
+			return (0);
  233
+		}
  234
+	}
  235
+	event_debug(("%s: adding event for %d", __func__, (int)ev->ev_fd));
  236
+	if (ev->ev_events & EV_READ) {
  237
+		if (do_fd_set(win32op, ev->ev_fd, 1)<0)
  238
+			return (-1);
  239
+	}
  240
+	if (ev->ev_events & EV_WRITE) {
  241
+		if (do_fd_set(win32op, ev->ev_fd, 0)<0)
  242
+			return (-1);
  243
+	}
  244
+
  245
+	if (win32op->n_events_alloc == win32op->n_events) {
  246
+		size_t sz;
  247
+		win32op->n_events_alloc *= 2;
  248
+		sz = sizeof(struct event*)*win32op->n_events_alloc;
  249
+		if (!(win32op->events = realloc(win32op->events, sz)))
  250
+			return (-1);
  251
+	}
  252
+	win32op->events[win32op->n_events++] = ev;
  253
+
  254
+	return (0);
  255
+}
  256
+
  257
+int
  258
+win32_del(void *op, struct event *ev)
  259
+{
  260
+	struct win32op *win32op = op;
  261
+	int i, found;
  262
+
  263
+	if (ev->ev_events & EV_SIGNAL)
  264
+		return ((int)signal(EVENT_SIGNAL(ev), SIG_IGN));
  265
+
  266
+	found = -1;
  267
+	for (i=0;i<win32op->n_events;++i) {
  268
+		if(win32op->events[i] == ev) {
  269
+			found = i;
  270
+			break;
  271
+		}
  272
+	}
  273
+	if (found < 0) {
  274
+		event_debug(("%s: Unable to remove non-inserted event for %d",
  275
+			     __func__, ev->ev_fd));
  276
+		return (-1);
  277
+	}
  278
+	event_debug(("%s: Removing event for %d", __func__, ev->ev_fd));
  279
+	if (ev->ev_events & EV_READ)
  280
+		do_fd_clear(win32op, ev->ev_fd, 1);
  281
+	if (ev->ev_events & EV_WRITE)
  282
+		do_fd_clear(win32op, ev->ev_fd, 0);
  283
+
  284
+	if (i != --win32op->n_events) {
  285
+		win32op->events[i] = win32op->events[win32op->n_events];
  286
+	}
  287
+
  288
+	return 0;
  289
+}
  290
+
  291
+static void
  292
+fd_set_copy(struct win_fd_set *out, const struct win_fd_set *in)
  293
+{
  294
+	out->fd_count = in->fd_count;
  295
+	memcpy(out->fd_array, in->fd_array, in->fd_count * (sizeof(SOCKET)));
  296
+}
  297
+
  298
+/*
  299
+  static void dump_fd_set(struct win_fd_set *s)
  300
+  {
  301
+  unsigned int i;
  302
+  printf("[ ");
  303
+  for(i=0;i<s->fd_count;++i)
  304
+  printf("%d ",(int)s->fd_array[i]);
  305
+  printf("]\n");
  306
+  }
  307
+*/
  308
+
  309
+int
  310
+win32_dispatch(struct event_base *base, void *op,
  311
+	       struct timeval *tv)
  312
+{
  313
+	struct win32op *win32op = op;
  314
+	int res = 0;
  315
+	int i;
  316
+	int fd_count;
  317
+
  318
+	fd_set_copy(win32op->readset_out, win32op->readset_in);
  319
+	fd_set_copy(win32op->exset_out, win32op->readset_in);
  320
+	fd_set_copy(win32op->writeset_out, win32op->writeset_in);
  321
+
  322
+	fd_count =
  323
+           (win32op->readset_out->fd_count > win32op->writeset_out->fd_count) ?
  324
+	    win32op->readset_out->fd_count : win32op->writeset_out->fd_count;
  325
+
  326
+	if (!fd_count) {
  327
+		/* Windows doesn't like you to call select() with no sockets */
  328
+		Sleep(timeval_to_ms(tv));
  329
+		signal_process();
  330
+		return (0);
  331
+	}
  332
+
  333
+	res = select(fd_count,
  334
+		     (struct fd_set*)win32op->readset_out,
  335
+		     (struct fd_set*)win32op->writeset_out,
  336
+		     (struct fd_set*)win32op->exset_out, tv);
  337
+
  338
+	event_debug(("%s: select returned %d", __func__, res));
  339
+
  340
+	if(res <= 0) {
  341
+		signal_process();
  342
+		return res;
  343
+	}
  344
+
  345
+	for (i=0;i<win32op->n_events;++i) {
  346
+		struct event *ev;
  347
+		int got = 0;
  348
+		ev = win32op->events[i];
  349
+		if ((ev->ev_events & EV_READ)) {
  350
+			if (FD_ISSET(ev->ev_fd, win32op->readset_out) ||
  351
+			    FD_ISSET(ev->ev_fd, win32op->exset_out)) {
  352
+				got |= EV_READ;
  353
+			}
  354
+		}
  355
+		if ((ev->ev_events & EV_WRITE)) {
  356
+			if (FD_ISSET(ev->ev_fd, win32op->writeset_out)) {
  357
+				got |= EV_WRITE;
  358
+			}
  359
+		}
  360
+		if (!got)
  361
+			continue;
  362
+		if (!(ev->ev_events & EV_PERSIST)) {
  363
+			event_del(ev);
  364
+		}
  365
+		event_active(ev,got,1);
  366
+	}
  367
+
  368
+	if (signal_recalc() == -1)
  369
+		return (-1);
  370
+
  371
+	return (0);
  372
+}
  373
+
  374
+void
  375
+win32_dealloc(void *arg)
  376
+{
  377
+	struct win32op *win32op = arg;
  378
+
  379
+	if (win32op->readset_in)
  380
+		free(win32op->readset_in);
  381
+	if (win32op->writeset_in)
  382
+		free(win32op->writeset_in);
  383
+	if (win32op->readset_out)
  384
+		free(win32op->readset_out);
  385
+	if (win32op->writeset_out)
  386
+		free(win32op->writeset_out);
  387
+	if (win32op->exset_out)
  388
+		free(win32op->exset_out);
  389
+	if (win32op->events)
  390
+		free(win32op->events);
  391
+
  392
+	memset(win32op, 0, sizeof(win32op));
  393
+	free(win32op);
  394
+}
  395
+
  396
+static void
  397
+signal_handler(int sig)
  398
+{
  399
+	evsigcaught[sig]++;
  400
+	signal_caught = 1;
  401
+}
  402
+
  403
+int
  404
+signal_recalc(void)
  405
+{
  406
+	struct event *ev;
  407
+
  408
+	/* Reinstall our signal handler. */
  409
+	TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  410
+		if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
  411
+			return (-1);
  412
+	}
  413
+	return (0);
  414
+}
  415
+
  416
+void
  417
+signal_process(void)
  418
+{
  419
+	struct event *ev;
  420
+	short ncalls;
  421
+
  422
+	TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  423
+		ncalls = evsigcaught[EVENT_SIGNAL(ev)];
  424
+		if (ncalls) {
  425
+			if (!(ev->ev_events & EV_PERSIST))
  426
+				event_del(ev);
  427
+			event_active(ev, EV_SIGNAL, ncalls);
  428
+		}
  429
+	}
  430
+
  431
+	memset(evsigcaught, 0, sizeof(evsigcaught));
  432
+	signal_caught = 0;
  433
+}
100  WIN32-Prj/event_test/event_test.dsp
... ...
@@ -0,0 +1,100 @@
  1
+# Microsoft Developer Studio Project File - Name="event_test" - Package Owner=<4>
  2
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
  3
+# ** DO NOT EDIT **
  4
+
  5
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
  6
+
  7
+CFG=event_test - Win32 Debug
  8
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
  9
+!MESSAGE use the Export Makefile command and run
  10
+!MESSAGE 
  11
+!MESSAGE NMAKE /f "event_test.mak".
  12
+!MESSAGE 
  13
+!MESSAGE You can specify a configuration when running NMAKE
  14
+!MESSAGE by defining the macro CFG on the command line. For example:
  15
+!MESSAGE 
  16
+!MESSAGE NMAKE /f "event_test.mak" CFG="event_test - Win32 Debug"
  17
+!MESSAGE 
  18
+!MESSAGE Possible choices for configuration are:
  19
+!MESSAGE 
  20
+!MESSAGE "event_test - Win32 Release" (based on "Win32 (x86) Console Application")
  21
+!MESSAGE "event_test - Win32 Debug" (based on "Win32 (x86) Console Application")
  22
+!MESSAGE 
  23
+
  24
+# Begin Project
  25
+# PROP AllowPerConfigDependencies 0
  26
+# PROP Scc_ProjName ""
  27
+# PROP Scc_LocalPath ""
  28
+CPP=cl.exe
  29
+RSC=rc.exe
  30
+
  31
+!IF  "$(CFG)" == "event_test - Win32 Release"
  32
+
  33
+# PROP BASE Use_MFC 0
  34
+# PROP BASE Use_Debug_Libraries 0
  35
+# PROP BASE Output_Dir "Release"
  36
+# PROP BASE Intermediate_Dir "Release"
  37
+# PROP BASE Target_Dir ""
  38
+# PROP Use_MFC 0
  39
+# PROP Use_Debug_Libraries 0
  40
+# PROP Output_Dir "Release"
  41
+# PROP Intermediate_Dir "Release"
  42
+# PROP Target_Dir ""
  43
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
  44
+# ADD CPP /nologo /W3 /GX /O2 /I "..\..\\" /I "..\..\WIN32-Code" /I "..\..\compat" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
  45
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
  46
+# ADD RSC /l 0x409 /d "NDEBUG"
  47
+BSC32=bscmake.exe
  48
+# ADD BASE BSC32 /nologo
  49
+# ADD BSC32 /nologo
  50
+LINK32=link.exe
  51
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
  52
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
  53
+
  54
+!ELSEIF  "$(CFG)" == "event_test - Win32 Debug"
  55
+
  56
+# PROP BASE Use_MFC 0
  57
+# PROP BASE Use_Debug_Libraries 1
  58
+# PROP BASE Output_Dir "Debug"
  59
+# PROP BASE Intermediate_Dir "Debug"
  60
+# PROP BASE Target_Dir ""
  61
+# PROP Use_MFC 0
  62
+# PROP Use_Debug_Libraries 1
  63
+# PROP Output_Dir "Debug"
  64
+# PROP Intermediate_Dir "Debug"
  65
+# PROP Target_Dir ""
  66
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
  67
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\\" /I "..\..\WIN32-Code" /I "..\..\compat" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
  68
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
  69
+# ADD RSC /l 0x409 /d "_DEBUG"
  70
+BSC32=bscmake.exe
  71
+# ADD BASE BSC32 /nologo
  72
+# ADD BSC32 /nologo
  73
+LINK32=link.exe
  74
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
  75
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
  76
+
  77
+!ENDIF 
  78
+
  79
+# Begin Target
  80
+
  81
+# Name "event_test - Win32 Release"
  82
+# Name "event_test - Win32 Debug"
  83
+# Begin Group "Source Files"
  84
+
  85
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
  86
+# Begin Source File
  87
+
  88
+SOURCE="..\..\sample\event-test.c"
  89
+# End Source File
  90
+# End Group
  91
+# Begin Group "Header Files"
  92
+
  93
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
  94
+# End Group
  95
+# Begin Group "Resource Files"
  96
+
  97
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
  98
+# End Group
  99
+# End Target
  100
+# End Project
180  WIN32-Prj/event_test/test.txt
... ...
@@ -0,0 +1,180 @@
  1
+  
  2
+  Platform SDK: File Storage 
  3
+ReadFile
  4
+The ReadFile function reads data from a file, starting at the position indicated by the file pointer. After the read operation has been completed, the file pointer is adjusted by the number of bytes actually read, unless the file handle is created with the overlapped attribute. If the file handle is created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the read operation. 
  5
+
  6
+This function is designed for both synchronous and asynchronous operation. The ReadFileEx function is designed solely for asynchronous operation. It lets an application perform other processing during a file read operation.
  7
+
  8
+BOOL ReadFile(
  9
+  HANDLE hFile,                // handle to file
  10
+  LPVOID lpBuffer,             // data buffer
  11
+  DWORD nNumberOfBytesToRead,  // number of bytes to read
  12
+  LPDWORD lpNumberOfBytesRead, // number of bytes read
  13
+  LPOVERLAPPED lpOverlapped    // overlapped buffer
  14
+);
  15
+Parameters
  16
+hFile 
  17
+[in] Handle to the file to be read. The file handle must have been created with GENERIC_READ access to the file. 
  18
+Windows NT/2000/XP: For asynchronous read operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept function. 
  19
+
  20
+Windows 95/98/Me: For asynchronous read operations, hFile can be a communications resource opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by socket or accept. You cannot perform asynchronous read operations on mailslots, named pipes, or disk files. 
  21
+
  22
+lpBuffer 
  23
+[out] Pointer to the buffer that receives the data read from the file. 
  24
+nNumberOfBytesToRead 
  25
+[in] Specifies the number of bytes to be read from the file. 
  26
+lpNumberOfBytesRead 
  27
+[out] Pointer to the variable that receives the number of bytes read. ReadFile sets this value to zero before doing any work or error checking. If this parameter is zero when ReadFile returns TRUE on a named pipe, the other end of the message-mode pipe called the WriteFile function with nNumberOfBytesToWrite set to zero. 
  28
+Windows NT/2000/XP: If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL. If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult. If hFile is associated with an I/O completion port, you can get the number of bytes read by calling GetQueuedCompletionStatus. 
  29
+
  30
+If I/O completion ports are used and you are using a callback routine to free the memory allocated to the OVERLAPPED structure pointed to by the lpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the deallocation. This memory corruption problem will cause an invalid number of bytes to be returned in this parameter. 
  31
+
  32
+Windows 95/98/Me: This parameter cannot be NULL. 
  33
+
  34
+lpOverlapped 
  35
+[in] Pointer to an OVERLAPPED structure. This structure is required if hFile was created with FILE_FLAG_OVERLAPPED. 
  36
+If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete. 
  37
+
  38
+If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile may return before the read operation has been completed. In this case, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue while the read operation finishes. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation. 
  39
+
  40
+If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile does not return until the operation has been completed. 
  41
+
  42
+Windows NT/2000/XP: If hFile is not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure. ReadFile does not return until the read operation has been completed. 
  43
+
  44
+Windows 95/98/Me: For operations on files, disks, pipes, or mailslots, this parameter must be NULL; a pointer to an OVERLAPPED structure causes the call to fail. However, Windows 95/98/Me supports overlapped I/O on serial and parallel ports. 
  45
+
  46
+Return Values
  47
+The ReadFile function returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs. 
  48
+
  49
+If the function succeeds, the return value is nonzero. 
  50
+
  51
+If the return value is nonzero and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation. However, if the file was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is FALSE and GetLastError returns ERROR_HANDLE_EOF when the file pointer goes beyond the current end of file.
  52
+
  53
+If the function fails, the return value is zero. To get extended error information, call GetLastError. 
  54
+
  55
+Remarks
  56
+If part of the file is locked by another process and the read operation overlaps the locked portion, this function fails. 
  57
+
  58
+An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING: 
  59
+
  60
+File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace function. 
  61
+File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes. 
  62
+Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size. 
  63
+Accessing the input buffer while a read operation is using the buffer may lead to corruption of the data read into that buffer. Applications must not read from, write to, reallocate, or free the input buffer that a read operation is using until the read operation completes.
  64
+
  65
+Characters can be read from the console input buffer by using ReadFile with a handle to console input. The console mode determines the exact behavior of the ReadFile function. 
  66
+
  67
+If a named pipe is being read in message mode and the next message is longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the message may be read by a subsequent call to the ReadFile or PeekNamedPipe function. 
  68
+
  69
+When reading from a communications device, the behavior of ReadFile is governed by the current communication time-outs as set and retrieved using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable results can occur if you fail to set the time-out values. For more information about communication time-outs, see COMMTIMEOUTS.
  70
+
  71
+If ReadFile attempts to read from a mailslot whose buffer is too small, the function returns FALSE and GetLastError returns ERROR_INSUFFICIENT_BUFFER. 
  72
+
  73
+If the anonymous write pipe handle has been closed and ReadFile attempts to read using the corresponding anonymous read pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE. 
  74
+
  75
+The ReadFile function may fail and return ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests. 
  76
+
  77
+The ReadFile code to check for the end-of-file condition (eof) differs for synchronous and asynchronous read operations.
  78
+
  79
+When a synchronous read operation reaches the end of a file, ReadFile returns TRUE and sets *lpNumberOfBytesRead to zero. The following sample code tests for end-of-file for a synchronous read operation:
  80
+
  81
+// Attempt a synchronous read operation. 
  82
+bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL) ; 
  83
+// Check for end of file. 
  84
+if (bResult &&  nBytesRead == 0, ) 
  85
+{ 
  86
+    // we're at the end of the file 
  87
+} 
  88
+An asynchronous read operation can encounter the end of a file during the initiating call to ReadFile, or during subsequent asynchronous operation. 
  89
+
  90
+If EOF is detected at ReadFile time for an asynchronous read operation, ReadFile returns FALSE and GetLastError returns ERROR_HANDLE_EOF.
  91
+
  92
+If EOF is detected during subsequent asynchronous operation, the call to GetOverlappedResult to obtain the results of that operation returns FALSE and GetLastError returns ERROR_HANDLE_EOF.
  93
+
  94
+To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED. 
  95
+
  96
+If you are attempting to read from a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX. 
  97
+
  98
+The following sample code illustrates testing for end-of-file for an asynchronous read operation:
  99
+
  100
+// set up overlapped structure fields 
  101
+gOverLapped.Offset     = 0; 
  102
+gOverLapped.OffsetHigh = 0; 
  103
+gOverLapped.hEvent     = hEvent; 
  104
+ 
  105
+// attempt an asynchronous read operation 
  106
+bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, 
  107
+    &gOverlapped) ; 
  108
+ 
  109
+// if there was a problem, or the async. operation's still pending ... 
  110
+if (!bResult) 
  111
+{ 
  112
+    // deal with the error code 
  113
+    switch (dwError = GetLastError()) 
  114
+    { 
  115
+        case ERROR_HANDLE_EOF: 
  116
+        { 
  117
+            // we have reached the end of the file 
  118
+            // during the call to ReadFile 
  119
+ 
  120
+            // code to handle that 
  121
+        } 
  122
+ 
  123
+        case ERROR_IO_PENDING: 
  124
+        { 
  125
+            // asynchronous i/o is still in progress 
  126
+ 
  127
+            // do something else for a while 
  128
+            GoDoSomethingElse() ; 
  129
+ 
  130
+            // check on the results of the asynchronous read 
  131
+            bResult = GetOverlappedResult(hFile, &gOverlapped, 
  132
+                &nBytesRead, FALSE) ; 
  133
+ 
  134
+            // if there was a problem ... 
  135
+            if (!bResult) 
  136
+            { 
  137
+                // deal with the error code 
  138
+                switch (dwError = GetLastError()) 
  139
+                { 
  140
+                    case ERROR_HANDLE_EOF: 
  141
+                    { 
  142
+                        // we have reached the end of
  143
+                        // the file during asynchronous
  144
+                        // operation
  145
+                    } 
  146
+ 
  147
+                    // deal with other error cases 
  148
+                } 
  149
+            } 
  150
+        } // end case 
  151
+ 
  152
+        // deal with other error cases 
  153
+ 
  154
+    } // end switch 
  155
+} // end if 
  156
+Example Code
  157
+For an example, see Reading, Writing, and Locking Files. 
  158
+
  159
+Requirements 
  160
+  Windows NT/2000/XP: Included in Windows NT 3.1 and later.
  161
+  Windows 95/98/Me: Included in Windows 95 and later.
  162
+  Header: Declared in Winbase.h; include Windows.h.
  163
+  Library: Use Kernel32.lib.
  164
+
  165
+See Also
  166
+File I/O Overview, File I/O Functions, CancelIo, CreateFile, GetCommTimeouts, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED, PeekNamedPipe, ReadFileEx, SetCommTimeouts, SetErrorMode, WriteFile 
  167
+
  168
+Platform SDK Release: November 2001  What did you think of this topic?
  169
+Let us know.  Order a Platform SDK CD Online
  170
+(U.S/Canada)   (International) 
  171
+
  172
+ 
  173
+
  174
+Requirements 
  175
+  Windows NT/2000/XP: Included in Windows NT 3.1 and later.
  176
+  Windows 95/98/Me: Included in Windows 95 and later.
  177
+  Header: Declared in Winbase.h; include Windows.h.
  178
+  Library: Use Kernel32.lib.
  179
+See Also
  180
+File I/O Overview, File I/O Functions, CancelIo, CreateFile, GetCommTimeouts, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED, PeekNamedPipe, ReadFileEx, SetCommTimeouts, SetErrorMode, WriteFile 
128  WIN32-Prj/libevent.dsp
... ...
@@ -0,0 +1,128 @@
  1
+# Microsoft Developer Studio Project File - Name="libevent" - Package Owner=<4>
  2
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
  3
+# ** DO NOT EDIT **
  4
+
  5
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
  6
+
  7
+CFG=libevent - Win32 Debug