void dispatch_wait2(dispatch_t * self, int timeout) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); if (-1 < self->fd) { struct epoll_event events[DISPATCH_EVENT_SIZE]; int rc = epoll_wait(self->fd, events, DISPATCH_EVENT_SIZE, timeout); if (0 < rc) { dump_memory(stdout, 0, events, sizeof(events)); } for (int n = 0; n < rc; n++) { dispatch_callback_t *cb = (dispatch_callback_t *) events[n].data.ptr; if (cb != NULL) { printf ("cb[%p] fd[%d] data[%p] ep->data.u64[%lld]\n", cb, cb->fd, cb->data, events[n].data.u64); if (cb->func != NULL) { // dispatch_event ev = {events[n].data.u64 >> 32, events[n].events}; dispatch_event_t ev = { cb->fd, events[n].events }; cb->func(&ev, cb->data); } } } } }
static void eval_interpolation_symbol(const char ** source_begin, const char * source_end, command_stack & command) { const char * start = *source_begin; const char * cursor = start; for(; cursor != source_end; cursor++) { expression::token_id token_id = expression::symbols[static_cast<std::size_t>(*cursor)]; if(token_id != expression::CHAR) { if(token_id != expression::ERROR) break; else { *source_begin = cursor; throw_unexpected(*cursor, "interpolation symbol"); } } } std::size_t length = cursor - start; command.push_argument_symbol(start, length); *source_begin = cursor - 1; }
void eval_reference(const char ** source_begin, const char * source_end, command_stack & command) { const char * start = *source_begin; if(*start == '&') *source_begin = ++start; for(const char * cursor = start; cursor != source_end; cursor++) { expression::token_id token_id = expression::symbols[static_cast<std::size_t>(*cursor)]; if(token_id != expression::CHAR) { *source_begin = cursor - 1; if(token_id != expression::ERROR) { std::size_t length = cursor - start; command.push_argument_symbol(start, length); return; } else { *source_begin = cursor; throw_unexpected(*cursor, "reference"); } } } *source_begin = source_end; throw parse_incomplete(); }
void dispatch_delete(dispatch_t * self) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); close(self->fd), self->fd = -1; array_delete(&self->events); }
void watch_delete(watch_t * self) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); close(self->fd), self->fd = -1; array_delete(&self->callbacks); }
void *__heap_alloc(heap_t * self, size_t size, const char *file, int line) { if (unlikely(self == NULL)) throw_unexpected(HEAP_NULL); size = max(align(size, self->alloc_size), self->alloc_size); size_t slab_pos = size / self->alloc_size - 1; if (unlikely(self->slab_size < slab_pos)) throw_unexpected(HEAP_ALLOC); if (unlikely(self->slab[slab_pos] == NULL)) self->slab[slab_pos] = slab_new(size, 0); return slab_alloc(self->slab[slab_pos]); }
void __heap_free(heap_t * self, void *ptr, const char *file, int line) { if (unlikely(self == NULL)) throw_unexpected(HEAP_NULL); void *data = (void *)((uint32_t) ptr & ~(self->page_size - 1)); cache_t *c = (cache_t *) (data + self->page_size - sizeof(cache_t)); cache_check(c); slab_free(cache_slab(c), ptr); }
void dispatch_remove(dispatch_t * self, int fd) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); if (unlikely(epoll_ctl(self->fd, EPOLL_CTL_DEL, fd, NULL))) throw_errno(errno); array_status(&self->events, fd, false); }
void timer_remove(timer * self, uint32_t wd) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); int rc = inotify_rm_timer(self->fd, wd); if (unlikely(rc == -1)) throw_errno(errno); array_status(&self->callbacks, wd, false); }
void watch_remove(watch_t * self, uint32_t wd) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); int rc = inotify_rm_watch(self->fd, wd); if (unlikely(rc == -1)) throw_errno(errno); array_status(&self->callbacks, wd, false); }
void watch_init(watch_t * self) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); if (self->fd != -1) close(self->fd), self->fd = -1; self->fd = inotify_init1(IN_CLOEXEC); if (unlikely(self->fd == -1)) throw_errno(errno); array_init(&self->callbacks, sizeof(watch_callback_t), WATCH_PAGE_SIZE); }
heap_t *__heap_new(size_t alloc_size, size_t page_size, const char *file, int line) { alloc_size = max(__round_pow2(alloc_size), CACHE_ALLOC_MIN); page_size = max(__round_pow2(page_size), CACHE_SIZE_MIN); if (alloc_size < CACHE_ALLOC_MIN || CACHE_ALLOC_MAX < alloc_size) throw_unexpected(HEAP_SIZE); if (page_size < CACHE_SIZE_MIN || CACHE_SIZE_MAX < page_size) throw_unexpected(HEAP_SIZE); heap_t *self = (heap_t *) MALLOC(sizeof(*self) + sizeof(*self->slab) * page_size / alloc_size); assert(self != NULL); self->page_size = page_size; self->alloc_size = alloc_size; self->slab_size = page_size / alloc_size; memset(self->slab, 0, self->slab_size * sizeof(*self->slab)); return self; }
void timer_init(timer * self, int clock) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); if (self->fd != -1) close(self->fd), self->fd = -1; self->fd = timerfd_create(clock, TFD_CLOEXEC); if (unlikely(self->fd == -1)) throw_errno(errno); vector_init(&self->callbacks, "callbacks", sizeof(timer_callback), TIMER_PAGE_SIZE); }
void dispatch_init(dispatch_t * self) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); if (self->fd != -1) close(self->fd), self->fd = -1; self->fd = epoll_create1(EPOLL_CLOEXEC); if (unlikely(self->fd == -1)) throw_errno(errno); array_init(&self->events, sizeof(struct epoll_event), DISPATCH_PAGE_SIZE); }
uint32_t timer_add(timer * self, timer_callback * cb) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); if (access(path, F_OK) != 0) throw_errno(errno); uint32_t wd = inotify_add_timer(self->fd, path, events); if (unlikely((int)wd == -1)) throw_errno(errno); if (cb != NULL) vcetor_put(&self->callbacks, wd, cb); return wd; }
void watch_wait(watch_t * self) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); /* FIX ME */ watch_event_t events[WATCH_EVENT_SIZE]; ssize_t n = read(self->fd, events, sizeof events); printf("n[%d]\n", n); for (ssize_t i = 0; i < (ssize_t) (n / sizeof *events); i++) printf("%d: wd[%d] mask[%x] cookie[%x] name[%.*s]\n", i, events[i].wd, events[i].mask, events[i].cookie, events[i].len, events[i].name); }
void timer_wait(timer * self) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); /* FIX ME */ timer_event events[timer_EVENT_SIZE]; int n = read(self->fd, events, sizeof events); printf("n[%d]\n", n); for (int i = 0; i < (n / sizeof *events); i++) printf("%d: wd[%d] mask[%x] cookie[%x] name[%.*s]\n", i, events[i].wd, events[i].mask, events[i].cookie, events[i].len, events[i].name); }
uint32_t watch_add(watch_t * self, const char *path, uint32_t events, watch_callback_t * cb) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); if (access(path, F_OK) != 0) throw_errno(errno); uint32_t wd = inotify_add_watch(self->fd, path, events); if (unlikely((int)wd == -1)) throw_errno(errno); if (cb != NULL) array_put(&self->callbacks, wd, cb, 1); return wd; }
int dispatch_add(dispatch_t * self, int fd, uint32_t events, dispatch_callback_t * cb) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); array_status(&self->events, fd, true); struct epoll_event *ep; ep = (struct epoll_event *)array_at(&self->events, fd); ep->events = events; ep->data.u64 = (uint64_t) fd << 32; ep->data.ptr = (void *)cb; if (unlikely(epoll_ctl(self->fd, EPOLL_CTL_ADD, fd, ep))) throw_errno(errno); return fd; }
int dispatch_fileno(dispatch_t * self) { if (unlikely(self == NULL)) throw_unexpected(DISPATCH_NULL); return self->fd; }
int timer_fileno(timer * self) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); return self->fd; }
void timer_delete(timer * self) { if (unlikely(self == NULL)) throw_unexpected(TIMER_NULL); close(self->fd), self->fd = -1; }
int watch_fileno(watch_t * self) { if (unlikely(self == NULL)) throw_unexpected(WATCH_NULL); return self->fd; }
void eval_word(const char ** source_begin, const char * source_end, command_stack & command) { const char * start = *source_begin; word_type type = WORD_INTEGER; parse_number_state number_parsing_stage = START_NUMBER; for(const char * cursor = start; cursor != source_end; cursor++) { char c = *cursor; expression::token_id token_id = expression::symbols[static_cast<std::size_t>(c)]; if(token_id != expression::CHAR && c != '/' && c != '#' && c != '&') { *source_begin = cursor - 1; std::size_t length = cursor - start; if(token_id != expression::ERROR && cursor != start) { if(number_parsing_stage == NAN) type = WORD_STRING; switch(type) { case WORD_INTEGER: { float n; std::sscanf(start, "%f", &n); command.push_argument(static_cast<int>(n)); break; } case WORD_REAL: { float n; std::sscanf(start, "%f", &n); command.push_argument(n); break; } case WORD_STRING: command.push_argument(start, length); break; } return; } else { *source_begin = cursor; throw_unexpected(c, "word"); } } switch(number_parsing_stage) { case START_NUMBER: number_parsing_stage = ((c >= '0' && c <= '9') || c == '-' ? INTEGER : NAN); break; case INTEGER: if(c >= '0' && c <= '9') break; if(c == '.') { number_parsing_stage = REAL; type = WORD_REAL; } else if(c == 'e' || c == 'E') number_parsing_stage = START_EXPONENT; else number_parsing_stage = NAN; break; case REAL: if(c >= '0' && c <= '9') break; number_parsing_stage = (c == 'e' || c == 'E' ? START_EXPONENT : NAN); break; case START_EXPONENT: number_parsing_stage = ((c >='0' && c<='9') || c== '-' || c=='+' ? EXPONENT_DIGITS : NAN); break; case EXPONENT_DIGITS: if(!(c >= '0' && c <= '9')) number_parsing_stage = NAN; break; default:; } } *source_begin = source_end; throw parse_incomplete(); }
void eval_expression(const char ** source_begin, const char * source_end, command_stack & command, bool is_sub_expression) { const char * start = *source_begin; if(is_sub_expression) { assert(*start == '('); start++; } std::size_t call_index = command.push_command(); bool first_argument = true; for(const char * cursor = start; cursor != source_end; cursor++) { char c = *cursor; expression::token_id token_id = expression::symbols[static_cast<std::size_t>(c)]; switch(token_id) { case expression::WHITESPACE: // Do nothing break; case expression::END_EXPRESSION: { *source_begin = cursor; if(!is_sub_expression) throw_unexpected(')', "expression"); command.call(call_index); return; } case expression::END_ROOT_EXPRESSION: { if(is_sub_expression) { if(c == ';') throw_unexpected(';', "expression"); break; // Allow new lines in sub expressions } *source_begin = cursor + 1; command.call(call_index); return; } case expression::START_EXPRESSION: { eval_expression(&cursor, source_end, command, true); first_argument = false; break; } case expression::START_SYMBOL: { eval_symbol(&cursor, source_end, command); first_argument = false; break; } case expression::START_REFERENCE: { eval_reference(&cursor, source_end, command); first_argument = false; break; } case expression::START_END_STRING: { eval_string(&cursor, source_end, command); first_argument = false; break; } case expression::START_MULTILINE_STRING: { eval_multiline_string(&cursor, source_end, command); first_argument = false; break; } case expression::CHAR: { if(!first_argument) eval_word(&cursor, source_end, command); else eval_reference(&cursor, source_end, command); first_argument = false; break; } case expression::START_COMMENT: { eval_comment(&cursor, source_end, command); break; } case expression::ERROR: default: *source_begin = cursor; throw_unexpected(c, "expression"); } } throw parse_incomplete(); }