/* Create a new loop */ struct mk_event_loop *mk_event_loop_create(int size) { void *backend; struct mk_event_loop *loop; backend = _mk_event_loop_create(size); if (!backend) { return NULL; } loop = mk_mem_alloc_z(sizeof(struct mk_event_loop)); if (!loop) { _mk_event_loop_destroy(backend); return NULL; } loop->events = mk_mem_alloc_z(sizeof(struct mk_event) * size); if (!loop->events) { _mk_event_loop_destroy(backend); mk_mem_free(loop); return NULL; } loop->size = size; loop->data = backend; return loop; }
static inline void *_mk_event_loop_create(int size) { struct mk_event_ctx *ctx; /* Override caller 'size', we always use FD_SETSIZE */ size = FD_SETSIZE; /* Main event context */ ctx = mk_mem_alloc_z(sizeof(struct mk_event_ctx)); if (!ctx) { return NULL; } FD_ZERO(&ctx->rfds); FD_ZERO(&ctx->wfds); /* Allocate space for events queue, re-use the struct mk_event */ ctx->events = mk_mem_alloc_z(sizeof(struct mk_event *) * size); if (!ctx->events) { mk_mem_free(ctx); return NULL; } /* Fired events (upon select(2) return) */ ctx->fired = mk_mem_alloc_z(sizeof(struct mk_event) * size); if (!ctx->fired) { mk_mem_free(ctx->events); mk_mem_free(ctx); return NULL; } ctx->queue_size = size; return ctx; }
struct mk_iov *mk_iov_create(int n, int offset) { int s_all; int s_iovec; int s_free_buf; void *p; struct mk_iov *iov; s_all = sizeof(struct mk_iov); /* main mk_iov structure */ s_iovec = (n * sizeof(struct iovec)); /* iovec array size */ s_free_buf = (n * sizeof(void *)); /* free buf array */ p = mk_mem_alloc_z(s_all + s_iovec + s_free_buf); if (!p) { return NULL; } /* Set pointer address */ iov = p; iov->io = p + sizeof(struct mk_iov); iov->buf_to_free = (void *) (p + sizeof(struct mk_iov) + s_iovec); mk_iov_init(iov, n, offset); return iov; }
static inline void *_mk_event_loop_create(int size) { int efd; struct mk_event_ctx *ctx; /* Main event context */ ctx = mk_mem_alloc_z(sizeof(struct mk_event_ctx)); if (!ctx) { return NULL; } /* Create the epoll instance */ #ifdef EPOLL_CLOEXEC efd = epoll_create1(EPOLL_CLOEXEC); #else efd = epoll_create(1); if (efd > 0) { if (fcntl(efd, F_SETFD, FD_CLOEXEC) == -1) { perror("fcntl"); } } #endif if (efd == -1) { mk_libc_error("epoll_create"); mk_mem_free(ctx); return NULL; } ctx->efd = efd; /* Allocate space for events queue */ ctx->events = mk_mem_alloc_z(sizeof(struct epoll_event) * size); if (!ctx->events) { close(ctx->efd); mk_mem_free(ctx); return NULL; } ctx->queue_size = size; return ctx; }
/* Creates a web service instance */ struct duda_service *duda_service_create(struct duda *d, char *root, char *log, char *data, char *html, char *service) { int ret; void *handle; struct duda_service *ds; struct duda_api_objects *api; if (!d) { return NULL; } /* Check access to root, log, data and html directories */ if (root) { ret = validate_dir(root); if (ret != 0) { return NULL; } } if (log) { ret = validate_dir(log); if (ret != 0) { return NULL; } } if (data) { ret = validate_dir(log); if (ret != 0) { return NULL; } } if (html) { ret = validate_dir(html); if (ret != 0) { return NULL; } } /* Validate the web service file */ handle = dlopen(service, RTLD_LAZY); if (!handle) { fprintf(stderr, "Error opening web service file '%s'\n", service); return NULL; } /* Create web service context */ ds = mk_mem_alloc_z(sizeof(struct duda_service)); if (!ds) { dlclose(handle); return NULL; } /* Root prefix path */ if (root) { ds->path_root = mk_string_dup(root); } /* * If root prefix path is set, for all incoming paths that are not * absolute, we prefix the path */ if (log) { ds->path_log = service_path(root, log); } if (data) { ds->path_data = service_path(root, data); } if (html) { ds->path_html = service_path(root, html); } if (service) { ds->path_service = service_path(root, service); } ds->dl_handle = handle; mk_list_add(&ds->_head, &d->services); /* Initialize references for API objects */ mk_list_init(&ds->router_list); api = duda_api_create(); map_internals(ds, api); return ds; }