A clone of btpd with my configuration changes.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

434 строки
10 KiB

  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. #include <winsock2.h>
  30. #include <windows.h>
  31. #include <sys/types.h>
  32. #include <sys/queue.h>
  33. #include <sys/tree.h>
  34. #include <signal.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <errno.h>
  39. #include <assert.h>
  40. #include "log.h"
  41. #include "event.h"
  42. #include "event-internal.h"
  43. #define XFREE(ptr) do { if (ptr) free(ptr); } while(0)
  44. extern struct event_list timequeue;
  45. extern struct event_list addqueue;
  46. extern struct event_list signalqueue;
  47. struct win_fd_set {
  48. u_int fd_count;
  49. SOCKET fd_array[1];
  50. };
  51. int evsigcaught[NSIG];
  52. volatile sig_atomic_t signal_caught = 0;
  53. /* MSDN says this is required to handle SIGFPE */
  54. volatile double SIGFPE_REQ = 0.0f;
  55. static void signal_handler(int sig);
  56. void signal_process(void);
  57. int signal_recalc(void);
  58. struct win32op {
  59. int fd_setsz;
  60. struct win_fd_set *readset_in;
  61. struct win_fd_set *writeset_in;
  62. struct win_fd_set *readset_out;
  63. struct win_fd_set *writeset_out;
  64. struct win_fd_set *exset_out;
  65. int n_events;
  66. int n_events_alloc;
  67. struct event **events;
  68. };
  69. void *win32_init (void);
  70. int win32_insert (void *, struct event *);
  71. int win32_del (void *, struct event *);
  72. int win32_recalc (struct event_base *base, void *, int);
  73. int win32_dispatch (struct event_base *base, void *, struct timeval *);
  74. void win32_dealloc (void *);
  75. struct eventop win32ops = {
  76. "win32",
  77. win32_init,
  78. win32_insert,
  79. win32_del,
  80. win32_recalc,
  81. win32_dispatch,
  82. win32_dealloc
  83. };
  84. #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET)))
  85. static int
  86. realloc_fd_sets(struct win32op *op, size_t new_size)
  87. {
  88. size_t size;
  89. assert(new_size >= op->readset_in->fd_count &&
  90. new_size >= op->writeset_in->fd_count);
  91. assert(new_size >= 1);
  92. size = FD_SET_ALLOC_SIZE(new_size);
  93. if (!(op->readset_in = realloc(op->readset_in, size)))
  94. return (-1);
  95. if (!(op->writeset_in = realloc(op->writeset_in, size)))
  96. return (-1);
  97. if (!(op->readset_out = realloc(op->readset_out, size)))
  98. return (-1);
  99. if (!(op->exset_out = realloc(op->exset_out, size)))
  100. return (-1);
  101. if (!(op->writeset_out = realloc(op->writeset_out, size)))
  102. return (-1);
  103. op->fd_setsz = new_size;
  104. return (0);
  105. }
  106. static int
  107. timeval_to_ms(struct timeval *tv)
  108. {
  109. return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000));
  110. }
  111. static int
  112. do_fd_set(struct win32op *op, SOCKET s, int read)
  113. {
  114. unsigned int i;
  115. struct win_fd_set *set = read ? op->readset_in : op->writeset_in;
  116. for (i=0;i<set->fd_count;++i) {
  117. if (set->fd_array[i]==s)
  118. return (0);
  119. }
  120. if (set->fd_count == op->fd_setsz) {
  121. if (realloc_fd_sets(op, op->fd_setsz*2))
  122. return (-1);
  123. /* set pointer will have changed and needs reiniting! */
  124. set = read ? op->readset_in : op->writeset_in;
  125. }
  126. set->fd_array[set->fd_count] = s;
  127. return (set->fd_count++);
  128. }
  129. static int
  130. do_fd_clear(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. if (--set->fd_count != i) {
  137. set->fd_array[i] = set->fd_array[set->fd_count];
  138. }
  139. return (0);
  140. }
  141. }
  142. return (0);
  143. }
  144. #define NEVENT 64
  145. void *
  146. win32_init(void)
  147. {
  148. struct win32op *winop;
  149. size_t size;
  150. if (!(winop = calloc(1, sizeof(struct win32op))))
  151. return NULL;
  152. winop->fd_setsz = NEVENT;
  153. size = FD_SET_ALLOC_SIZE(NEVENT);
  154. if (!(winop->readset_in = malloc(size)))
  155. goto err;
  156. if (!(winop->writeset_in = malloc(size)))
  157. goto err;
  158. if (!(winop->readset_out = malloc(size)))
  159. goto err;
  160. if (!(winop->writeset_out = malloc(size)))
  161. goto err;
  162. if (!(winop->exset_out = malloc(size)))
  163. goto err;
  164. winop->n_events = 0;
  165. winop->n_events_alloc = NEVENT;
  166. if (!(winop->events = malloc(NEVENT*sizeof(struct event*))))
  167. goto err;
  168. winop->readset_in->fd_count = winop->writeset_in->fd_count = 0;
  169. winop->readset_out->fd_count = winop->writeset_out->fd_count
  170. = winop->exset_out->fd_count = 0;
  171. return (winop);
  172. err:
  173. XFREE(winop->readset_in);
  174. XFREE(winop->writeset_in);
  175. XFREE(winop->readset_out);
  176. XFREE(winop->writeset_out);
  177. XFREE(winop->exset_out);
  178. XFREE(winop->events);
  179. XFREE(winop);
  180. return (NULL);
  181. }
  182. int
  183. win32_recalc(struct event_base *base, void *arg, int max)
  184. {
  185. return (signal_recalc());
  186. }
  187. int
  188. win32_insert(void *op, struct event *ev)
  189. {
  190. struct win32op *win32op = op;
  191. int i;
  192. if (ev->ev_events & EV_SIGNAL) {
  193. if (ev->ev_events & (EV_READ|EV_WRITE))
  194. event_errx(1, "%s: EV_SIGNAL incompatible use",
  195. __func__);
  196. if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
  197. return (-1);
  198. return (0);
  199. }
  200. if (!(ev->ev_events & (EV_READ|EV_WRITE)))
  201. return (0);
  202. for (i=0;i<win32op->n_events;++i) {
  203. if(win32op->events[i] == ev) {
  204. event_debug(("%s: Event for %d already inserted.",
  205. __func__, (int)ev->ev_fd));
  206. return (0);
  207. }
  208. }
  209. event_debug(("%s: adding event for %d", __func__, (int)ev->ev_fd));
  210. if (ev->ev_events & EV_READ) {
  211. if (do_fd_set(win32op, ev->ev_fd, 1)<0)
  212. return (-1);
  213. }
  214. if (ev->ev_events & EV_WRITE) {
  215. if (do_fd_set(win32op, ev->ev_fd, 0)<0)
  216. return (-1);
  217. }
  218. if (win32op->n_events_alloc == win32op->n_events) {
  219. size_t sz;
  220. win32op->n_events_alloc *= 2;
  221. sz = sizeof(struct event*)*win32op->n_events_alloc;
  222. if (!(win32op->events = realloc(win32op->events, sz)))
  223. return (-1);
  224. }
  225. win32op->events[win32op->n_events++] = ev;
  226. return (0);
  227. }
  228. int
  229. win32_del(void *op, struct event *ev)
  230. {
  231. struct win32op *win32op = op;
  232. int i, found;
  233. if (ev->ev_events & EV_SIGNAL)
  234. return ((int)signal(EVENT_SIGNAL(ev), SIG_IGN));
  235. found = -1;
  236. for (i=0;i<win32op->n_events;++i) {
  237. if(win32op->events[i] == ev) {
  238. found = i;
  239. break;
  240. }
  241. }
  242. if (found < 0) {
  243. event_debug(("%s: Unable to remove non-inserted event for %d",
  244. __func__, ev->ev_fd));
  245. return (-1);
  246. }
  247. event_debug(("%s: Removing event for %d", __func__, ev->ev_fd));
  248. if (ev->ev_events & EV_READ)
  249. do_fd_clear(win32op, ev->ev_fd, 1);
  250. if (ev->ev_events & EV_WRITE)
  251. do_fd_clear(win32op, ev->ev_fd, 0);
  252. if (i != --win32op->n_events) {
  253. win32op->events[i] = win32op->events[win32op->n_events];
  254. }
  255. return 0;
  256. }
  257. static void
  258. fd_set_copy(struct win_fd_set *out, const struct win_fd_set *in)
  259. {
  260. out->fd_count = in->fd_count;
  261. memcpy(out->fd_array, in->fd_array, in->fd_count * (sizeof(SOCKET)));
  262. }
  263. /*
  264. static void dump_fd_set(struct win_fd_set *s)
  265. {
  266. unsigned int i;
  267. printf("[ ");
  268. for(i=0;i<s->fd_count;++i)
  269. printf("%d ",(int)s->fd_array[i]);
  270. printf("]\n");
  271. }
  272. */
  273. int
  274. win32_dispatch(struct event_base *base, void *op,
  275. struct timeval *tv)
  276. {
  277. struct win32op *win32op = op;
  278. int res = 0;
  279. int i;
  280. int fd_count;
  281. fd_set_copy(win32op->readset_out, win32op->readset_in);
  282. fd_set_copy(win32op->exset_out, win32op->readset_in);
  283. fd_set_copy(win32op->writeset_out, win32op->writeset_in);
  284. fd_count =
  285. (win32op->readset_out->fd_count > win32op->writeset_out->fd_count) ?
  286. win32op->readset_out->fd_count : win32op->writeset_out->fd_count;
  287. if (!fd_count) {
  288. /* Windows doesn't like you to call select() with no sockets */
  289. Sleep(timeval_to_ms(tv));
  290. signal_process();
  291. return (0);
  292. }
  293. res = select(fd_count,
  294. (struct fd_set*)win32op->readset_out,
  295. (struct fd_set*)win32op->writeset_out,
  296. (struct fd_set*)win32op->exset_out, tv);
  297. event_debug(("%s: select returned %d", __func__, res));
  298. if(res <= 0) {
  299. signal_process();
  300. return res;
  301. }
  302. for (i=0;i<win32op->n_events;++i) {
  303. struct event *ev;
  304. int got = 0;
  305. ev = win32op->events[i];
  306. if ((ev->ev_events & EV_READ)) {
  307. if (FD_ISSET(ev->ev_fd, win32op->readset_out) ||
  308. FD_ISSET(ev->ev_fd, win32op->exset_out)) {
  309. got |= EV_READ;
  310. }
  311. }
  312. if ((ev->ev_events & EV_WRITE)) {
  313. if (FD_ISSET(ev->ev_fd, win32op->writeset_out)) {
  314. got |= EV_WRITE;
  315. }
  316. }
  317. if (!got)
  318. continue;
  319. if (!(ev->ev_events & EV_PERSIST)) {
  320. event_del(ev);
  321. }
  322. event_active(ev,got,1);
  323. }
  324. if (signal_recalc() == -1)
  325. return (-1);
  326. return (0);
  327. }
  328. void
  329. win32_dealloc(void *arg)
  330. {
  331. struct win32op *win32op = arg;
  332. if (win32op->readset_in)
  333. free(win32op->readset_in);
  334. if (win32op->writeset_in)
  335. free(win32op->writeset_in);
  336. if (win32op->readset_out)
  337. free(win32op->readset_out);
  338. if (win32op->writeset_out)
  339. free(win32op->writeset_out);
  340. if (win32op->exset_out)
  341. free(win32op->exset_out);
  342. if (win32op->events)
  343. free(win32op->events);
  344. memset(win32op, 0, sizeof(win32op));
  345. free(win32op);
  346. }
  347. static void
  348. signal_handler(int sig)
  349. {
  350. evsigcaught[sig]++;
  351. signal_caught = 1;
  352. }
  353. int
  354. signal_recalc(void)
  355. {
  356. struct event *ev;
  357. /* Reinstall our signal handler. */
  358. TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  359. if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1)
  360. return (-1);
  361. }
  362. return (0);
  363. }
  364. void
  365. signal_process(void)
  366. {
  367. struct event *ev;
  368. short ncalls;
  369. TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
  370. ncalls = evsigcaught[EVENT_SIGNAL(ev)];
  371. if (ncalls) {
  372. if (!(ev->ev_events & EV_PERSIST))
  373. event_del(ev);
  374. event_active(ev, EV_SIGNAL, ncalls);
  375. }
  376. }
  377. memset(evsigcaught, 0, sizeof(evsigcaught));
  378. signal_caught = 0;
  379. }