00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 struct timed_event {
00025 struct timed_event *next, *prev;
00026 struct event_context *event_ctx;
00027 struct timeval when;
00028 const char *event_name;
00029 void (*handler)(struct event_context *event_ctx,
00030 struct timed_event *te,
00031 const struct timeval *now,
00032 void *private_data);
00033 void *private_data;
00034 };
00035
00036 struct fd_event {
00037 struct fd_event *prev, *next;
00038 struct event_context *event_ctx;
00039 int fd;
00040 uint16_t flags;
00041 void (*handler)(struct event_context *event_ctx,
00042 struct fd_event *event,
00043 uint16 flags,
00044 void *private_data);
00045 void *private_data;
00046 };
00047
00048 #define EVENT_FD_WRITEABLE(fde) \
00049 event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
00050 #define EVENT_FD_READABLE(fde) \
00051 event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
00052
00053 #define EVENT_FD_NOT_WRITEABLE(fde) \
00054 event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
00055 #define EVENT_FD_NOT_READABLE(fde) \
00056 event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
00057
00058 struct event_context {
00059 struct timed_event *timed_events;
00060 struct fd_event *fd_events;
00061 };
00062
00063 static int timed_event_destructor(struct timed_event *te)
00064 {
00065 DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
00066 te->event_name));
00067 DLIST_REMOVE(te->event_ctx->timed_events, te);
00068 return 0;
00069 }
00070
00071
00072
00073
00074
00075 static void add_event_by_time(struct timed_event *te)
00076 {
00077 struct event_context *ctx = te->event_ctx;
00078 struct timed_event *last_te, *cur_te;
00079
00080
00081 last_te = NULL;
00082 for (cur_te = ctx->timed_events; cur_te; cur_te = cur_te->next) {
00083
00084 if (!timeval_is_zero(&cur_te->when) &&
00085 timeval_compare(&te->when, &cur_te->when) < 0) {
00086 break;
00087 }
00088 last_te = cur_te;
00089 }
00090
00091 DLIST_ADD_AFTER(ctx->timed_events, te, last_te);
00092 }
00093
00094
00095
00096
00097
00098
00099
00100 struct timed_event *event_add_timed(struct event_context *event_ctx,
00101 TALLOC_CTX *mem_ctx,
00102 struct timeval when,
00103 const char *event_name,
00104 void (*handler)(struct event_context *event_ctx,
00105 struct timed_event *te,
00106 const struct timeval *now,
00107 void *private_data),
00108 void *private_data)
00109 {
00110 struct timed_event *te;
00111
00112 te = TALLOC_P(mem_ctx, struct timed_event);
00113 if (te == NULL) {
00114 DEBUG(0, ("talloc failed\n"));
00115 return NULL;
00116 }
00117
00118 te->event_ctx = event_ctx;
00119 te->when = when;
00120 te->event_name = event_name;
00121 te->handler = handler;
00122 te->private_data = private_data;
00123
00124 add_event_by_time(te);
00125
00126 talloc_set_destructor(te, timed_event_destructor);
00127
00128 DEBUG(10, ("Added timed event \"%s\": %lx\n", event_name,
00129 (unsigned long)te));
00130 return te;
00131 }
00132
00133 static int fd_event_destructor(struct fd_event *fde)
00134 {
00135 struct event_context *event_ctx = fde->event_ctx;
00136
00137 DLIST_REMOVE(event_ctx->fd_events, fde);
00138 return 0;
00139 }
00140
00141 struct fd_event *event_add_fd(struct event_context *event_ctx,
00142 TALLOC_CTX *mem_ctx,
00143 int fd, uint16_t flags,
00144 void (*handler)(struct event_context *event_ctx,
00145 struct fd_event *event,
00146 uint16 flags,
00147 void *private_data),
00148 void *private_data)
00149 {
00150 struct fd_event *fde;
00151
00152 if (!(fde = TALLOC_P(mem_ctx, struct fd_event))) {
00153 return NULL;
00154 }
00155
00156 fde->event_ctx = event_ctx;
00157 fde->fd = fd;
00158 fde->flags = flags;
00159 fde->handler = handler;
00160 fde->private_data = private_data;
00161
00162 DLIST_ADD(event_ctx->fd_events, fde);
00163
00164 talloc_set_destructor(fde, fd_event_destructor);
00165 return fde;
00166 }
00167
00168 void event_fd_set_writeable(struct fd_event *fde)
00169 {
00170 fde->flags |= EVENT_FD_WRITE;
00171 }
00172
00173 void event_fd_set_not_writeable(struct fd_event *fde)
00174 {
00175 fde->flags &= ~EVENT_FD_WRITE;
00176 }
00177
00178 void event_fd_set_readable(struct fd_event *fde)
00179 {
00180 fde->flags |= EVENT_FD_READ;
00181 }
00182
00183 void event_fd_set_not_readable(struct fd_event *fde)
00184 {
00185 fde->flags &= ~EVENT_FD_READ;
00186 }
00187
00188 void event_add_to_select_args(struct event_context *event_ctx,
00189 const struct timeval *now,
00190 fd_set *read_fds, fd_set *write_fds,
00191 struct timeval *timeout, int *maxfd)
00192 {
00193 struct fd_event *fde;
00194 struct timeval diff;
00195
00196 for (fde = event_ctx->fd_events; fde; fde = fde->next) {
00197 if (fde->flags & EVENT_FD_READ) {
00198 FD_SET(fde->fd, read_fds);
00199 }
00200 if (fde->flags & EVENT_FD_WRITE) {
00201 FD_SET(fde->fd, write_fds);
00202 }
00203
00204 if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE))
00205 && (fde->fd > *maxfd)) {
00206 *maxfd = fde->fd;
00207 }
00208 }
00209
00210 if (event_ctx->timed_events == NULL) {
00211 return;
00212 }
00213
00214 diff = timeval_until(now, &event_ctx->timed_events->when);
00215 *timeout = timeval_min(timeout, &diff);
00216 }
00217
00218 BOOL run_events(struct event_context *event_ctx,
00219 int selrtn, fd_set *read_fds, fd_set *write_fds)
00220 {
00221 BOOL fired = False;
00222 struct fd_event *fde, *next;
00223
00224
00225
00226
00227 while (event_ctx->timed_events) {
00228 struct timeval now;
00229 GetTimeOfDay(&now);
00230
00231 if (timeval_compare(
00232 &now, &event_ctx->timed_events->when) < 0) {
00233
00234 DEBUG(11, ("run_events: Nothing to do\n"));
00235 break;
00236 }
00237
00238 DEBUG(10, ("Running event \"%s\" %lx\n",
00239 event_ctx->timed_events->event_name,
00240 (unsigned long)event_ctx->timed_events));
00241
00242 event_ctx->timed_events->handler(
00243 event_ctx,
00244 event_ctx->timed_events, &now,
00245 event_ctx->timed_events->private_data);
00246
00247 fired = True;
00248 }
00249
00250 if (fired) {
00251
00252
00253
00254
00255 return True;
00256 }
00257
00258 if (selrtn == 0) {
00259
00260
00261
00262 return fired;
00263 }
00264
00265 for (fde = event_ctx->fd_events; fde; fde = next) {
00266 uint16 flags = 0;
00267
00268 next = fde->next;
00269 if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
00270 if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
00271
00272 if (flags) {
00273 fde->handler(event_ctx, fde, flags, fde->private_data);
00274 fired = True;
00275 }
00276 }
00277
00278 return fired;
00279 }
00280
00281
00282 struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
00283 struct timeval *to_ret)
00284 {
00285 struct timeval now;
00286
00287 if (event_ctx->timed_events == NULL) {
00288 return NULL;
00289 }
00290
00291 now = timeval_current();
00292 *to_ret = timeval_until(&now, &event_ctx->timed_events->when);
00293
00294 DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec,
00295 (int)to_ret->tv_usec));
00296
00297 return to_ret;
00298 }
00299
00300 struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
00301 {
00302 return TALLOC_ZERO_P(NULL, struct event_context);
00303 }
00304
00305 int set_event_dispatch_time(struct event_context *event_ctx,
00306 const char *event_name, struct timeval when)
00307 {
00308 struct timed_event *te;
00309
00310 for (te = event_ctx->timed_events; te; te = te->next) {
00311 if (strcmp(event_name, te->event_name) == 0) {
00312 DLIST_REMOVE(event_ctx->timed_events, te);
00313 te->when = when;
00314 add_event_by_time(te);
00315 return 1;
00316 }
00317 }
00318 return 0;
00319 }
00320
00321
00322
00323 int cancel_named_event(struct event_context *event_ctx,
00324 const char *event_name)
00325 {
00326 struct timed_event *te;
00327
00328 for (te = event_ctx->timed_events; te; te = te->next) {
00329 if (strcmp(event_name, te->event_name) == 0) {
00330 TALLOC_FREE(te);
00331 return 1;
00332 }
00333 }
00334 return 0;
00335 }