Changeset 988 for vendor/current/source3/lib/events.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/lib/events.c
r740 r988 3 3 Timed event library. 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 Copyright (C) Volker Lendecke 2005 5 Copyright (C) Volker Lendecke 2005-2007 6 6 7 7 This program is free software; you can redistribute it and/or modify … … 43 43 state = (struct tevent_poll_private *)ev->additional_data; 44 44 if (state == NULL) { 45 state = TALLOC_ZERO_P(ev, struct tevent_poll_private);45 state = talloc_zero(ev, struct tevent_poll_private); 46 46 ev->additional_data = (void *)state; 47 47 if (state == NULL) { … … 60 60 61 61 for (fde = ev->fd_events; fde != NULL; fde = fde->next) { 62 if (fde->flags & ( EVENT_FD_READ|EVENT_FD_WRITE)) {62 if (fde->flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) { 63 63 num_fds += 1; 64 64 if (fde->fd > max_fd) { … … 91 91 92 92 if (talloc_array_length(state->pollfd_idx) < idx_len) { 93 state->pollfd_idx = TALLOC_REALLOC_ARRAY(93 state->pollfd_idx = talloc_realloc( 94 94 state, state->pollfd_idx, int, idx_len); 95 95 if (state->pollfd_idx == NULL) { … … 102 102 num_pollfds = *pnum_pfds; 103 103 104 /* 105 * The +1 is for the sys_poll calling convention. It expects 106 * an array 1 longer for the signal pipe 107 */ 108 109 if (talloc_array_length(fds) < num_pollfds + num_fds + 1) { 110 fds = TALLOC_REALLOC_ARRAY(mem_ctx, fds, struct pollfd, 111 num_pollfds + num_fds + 1); 104 if (talloc_array_length(fds) < num_pollfds + num_fds) { 105 fds = talloc_realloc(mem_ctx, fds, struct pollfd, 106 num_pollfds + num_fds); 112 107 if (fds == NULL) { 113 108 DEBUG(10, ("talloc_realloc failed\n")); … … 132 127 struct pollfd *pfd; 133 128 134 if ((fde->flags & ( EVENT_FD_READ|EVENT_FD_WRITE)) == 0) {129 if ((fde->flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) == 0) { 135 130 continue; 136 131 } … … 152 147 pfd->fd = fde->fd; 153 148 154 if (fde->flags & EVENT_FD_READ) {149 if (fde->flags & TEVENT_FD_READ) { 155 150 pfd->events |= (POLLIN|POLLHUP); 156 151 } 157 if (fde->flags & EVENT_FD_WRITE) {152 if (fde->flags & TEVENT_FD_WRITE) { 158 153 pfd->events |= POLLOUT; 159 154 } … … 188 183 int *pollfd_idx; 189 184 struct tevent_fd *fde; 190 struct timeval now;191 185 192 186 if (ev->signal_events && … … 200 194 } 201 195 202 GetTimeOfDay(&now);203 204 if ((ev->timer_events != NULL)205 && (timeval_compare(&now, &ev->timer_events->next_event) >= 0)) {206 /* this older events system did not auto-free timed207 events on running them, and had a race condition208 where the event could be called twice if the209 talloc_free of the te happened after the callback210 made a call which invoked the event loop. To avoid211 this while still allowing old code which frees the212 te, we need to create a temporary context which213 will be used to ensure the te is freed. We also214 remove the te from the timed event list before we215 call the handler, to ensure we can't loop */216 217 struct tevent_timer *te = ev->timer_events;218 TALLOC_CTX *tmp_ctx = talloc_new(ev);219 220 DEBUG(10, ("Running timed event \"%s\" %p\n",221 ev->timer_events->handler_name, ev->timer_events));222 223 DLIST_REMOVE(ev->timer_events, te);224 talloc_steal(tmp_ctx, te);225 226 te->handler(ev, te, now, te->private_data);227 228 talloc_free(tmp_ctx);229 return true;230 }231 232 196 if (pollrtn <= 0) { 197 struct timeval tval; 198 199 tval = tevent_common_loop_timer_delay(ev); 200 if (tevent_timeval_is_zero(&tval)) { 201 return true; 202 } 203 233 204 /* 234 205 * No fd ready … … 242 213 for (fde = ev->fd_events; fde; fde = fde->next) { 243 214 struct pollfd *pfd; 244 uint16 flags = 0;245 246 if ((fde->flags & ( EVENT_FD_READ|EVENT_FD_WRITE)) == 0) {215 uint16_t flags = 0; 216 217 if ((fde->flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) == 0) { 247 218 continue; 248 219 } … … 264 235 265 236 if (pfd->revents & (POLLHUP|POLLERR)) { 266 /* If we only wait for EVENT_FD_WRITE, we237 /* If we only wait for TEVENT_FD_WRITE, we 267 238 should not tell the event handler about it, 268 239 and remove the writable flag, as we only 269 240 report errors when waiting for read events 270 241 to match the select behavior. */ 271 if (!(fde->flags & EVENT_FD_READ)) {272 EVENT_FD_NOT_WRITEABLE(fde);242 if (!(fde->flags & TEVENT_FD_READ)) { 243 TEVENT_FD_NOT_WRITEABLE(fde); 273 244 continue; 274 245 } 275 flags |= EVENT_FD_READ;246 flags |= TEVENT_FD_READ; 276 247 } 277 248 278 249 if (pfd->revents & POLLIN) { 279 flags |= EVENT_FD_READ;250 flags |= TEVENT_FD_READ; 280 251 } 281 252 if (pfd->revents & POLLOUT) { 282 flags |= EVENT_FD_WRITE;253 flags |= TEVENT_FD_WRITE; 283 254 } 284 255 if (flags & fde->flags) { 285 DLIST_DEMOTE(ev->fd_events, fde , struct tevent_fd);256 DLIST_DEMOTE(ev->fd_events, fde); 286 257 fde->handler(ev, fde, flags, fde->private_data); 287 258 return true; … … 320 291 int num_pfds; 321 292 int ret; 293 int poll_errno; 322 294 323 295 timeout = INT_MAX; … … 339 311 } 340 312 341 ret = sys_poll(state->pfds, num_pfds, timeout); 313 tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_WAIT); 314 ret = poll(state->pfds, num_pfds, timeout); 315 poll_errno = errno; 316 tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); 317 errno = poll_errno; 318 342 319 if (ret == -1 && errno != EINTR) { 343 320 tevent_debug(ev, TEVENT_DEBUG_FATAL, … … 414 391 } 415 392 416 /*417 this is used to catch debug messages from events418 */419 static void s3_event_debug(void *context, enum tevent_debug_level level,420 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);421 422 static void s3_event_debug(void *context, enum tevent_debug_level level,423 const char *fmt, va_list ap)424 {425 int samba_level = -1;426 char *s = NULL;427 switch (level) {428 case TEVENT_DEBUG_FATAL:429 samba_level = 0;430 break;431 case TEVENT_DEBUG_ERROR:432 samba_level = 1;433 break;434 case TEVENT_DEBUG_WARNING:435 samba_level = 2;436 break;437 case TEVENT_DEBUG_TRACE:438 samba_level = 11;439 break;440 441 };442 if (vasprintf(&s, fmt, ap) == -1) {443 return;444 }445 DEBUG(samba_level, ("s3_event: %s", s));446 free(s);447 }448 449 393 struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx) 450 394 { … … 455 399 ev = tevent_context_init_byname(mem_ctx, "s3"); 456 400 if (ev) { 457 tevent_set_debug(ev, s3_event_debug, NULL);401 samba_tevent_set_debug(ev, "s3_tevent"); 458 402 } 459 403 … … 461 405 } 462 406 407 struct idle_event { 408 struct tevent_timer *te; 409 struct timeval interval; 410 char *name; 411 bool (*handler)(const struct timeval *now, void *private_data); 412 void *private_data; 413 }; 414 415 static void smbd_idle_event_handler(struct tevent_context *ctx, 416 struct tevent_timer *te, 417 struct timeval now, 418 void *private_data) 419 { 420 struct idle_event *event = 421 talloc_get_type_abort(private_data, struct idle_event); 422 423 TALLOC_FREE(event->te); 424 425 DEBUG(10,("smbd_idle_event_handler: %s %p called\n", 426 event->name, event->te)); 427 428 if (!event->handler(&now, event->private_data)) { 429 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n", 430 event->name, event->te)); 431 /* Don't repeat, delete ourselves */ 432 TALLOC_FREE(event); 433 return; 434 } 435 436 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n", 437 event->name, event->te)); 438 439 event->te = tevent_add_timer(ctx, event, 440 timeval_sum(&now, &event->interval), 441 smbd_idle_event_handler, event); 442 443 /* We can't do much but fail here. */ 444 SMB_ASSERT(event->te != NULL); 445 } 446 447 struct idle_event *event_add_idle(struct tevent_context *event_ctx, 448 TALLOC_CTX *mem_ctx, 449 struct timeval interval, 450 const char *name, 451 bool (*handler)(const struct timeval *now, 452 void *private_data), 453 void *private_data) 454 { 455 struct idle_event *result; 456 struct timeval now = timeval_current(); 457 458 result = talloc(mem_ctx, struct idle_event); 459 if (result == NULL) { 460 DEBUG(0, ("talloc failed\n")); 461 return NULL; 462 } 463 464 result->interval = interval; 465 result->handler = handler; 466 result->private_data = private_data; 467 468 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) { 469 DEBUG(0, ("talloc failed\n")); 470 TALLOC_FREE(result); 471 return NULL; 472 } 473 474 result->te = tevent_add_timer(event_ctx, result, 475 timeval_sum(&now, &interval), 476 smbd_idle_event_handler, result); 477 if (result->te == NULL) { 478 DEBUG(0, ("event_add_timed failed\n")); 479 TALLOC_FREE(result); 480 return NULL; 481 } 482 483 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te)); 484 return result; 485 } 486
Note:
See TracChangeset
for help on using the changeset viewer.