static void broadcast(struct ns_connection *nc, const char *msg, size_t len) { struct ns_connection *c; char buf[500]; snprintf(buf, sizeof(buf), "%p %.*s", nc, (int) len, msg); for (c = ns_next(nc->mgr, NULL); c != NULL; c = ns_next(nc->mgr, c)) { ns_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, strlen(buf)); } }
static void ns_mgr_handle_ctl_sock(struct ns_mgr *mgr) { struct ctl_msg ctl_msg; int len = (int) NS_RECV_FUNC(mgr->ctl[1], (char *) &ctl_msg, sizeof(ctl_msg), 0); NS_SEND_FUNC(mgr->ctl[1], ctl_msg.message, 1, 0); if (len >= (int) sizeof(ctl_msg.callback) && ctl_msg.callback != NULL) { struct ns_connection *nc; for (nc = ns_next(mgr, NULL); nc != NULL; nc = ns_next(mgr, nc)) { ctl_msg.callback(nc, NS_POLL, ctl_msg.message); } } }
static void server_handler(struct ns_connection *nc, enum ns_event ev, void *p) { (void) p; if (ev == NS_RECV) { // Push received message to all ncections struct iobuf *io = &nc->recv_iobuf; struct ns_connection *c; for (c = ns_next(nc->mgr, NULL); c != NULL; c = ns_next(nc->mgr, c)) { ns_send(c, io->buf, io->len); } iobuf_remove(io, io->len); } }
size_t list_modules(const struct module **p_arr, size_t arr_size, size_t offset) { int ret = 0; int iter_cnt = 0; struct ns_iter iter; ns_init_iterator(&iter, NS_TYPE_MODULE); while (1) { struct module *module = (struct module *) ns_next(&iter); if (!module) break; if (iter_cnt++ < offset) continue; if (ret >= arr_size) break; p_arr[ret++] = module; } ns_release_iterator(&iter); return ret; }
size_t list_mclasses(const struct mclass **p_arr, size_t arr_size, size_t offset) { int ret = 0; int iter_cnt = 0; struct ns_iter iter; ns_init_iterator(&iter, NS_TYPE_MCLASS); while (1) { struct mclass *mc_obj = (struct mclass *) ns_next(&iter); if (!mc_obj) break; if (iter_cnt++ < offset) continue; if (ret >= arr_size) break; p_arr[ret++] = mc_obj; } ns_release_iterator(&iter); return ret; }
size_t list_drivers(const struct driver **p_arr, size_t arr_size, size_t offset) { int ret = 0; int iter_cnt = 0; struct ns_iter iter; ns_init_iterator(&iter, NS_TYPE_DRIVER); while (1) { struct driver* driver = (struct driver *) ns_next(&iter); if (!driver) break; if (iter_cnt++ < offset) continue; if (ret >= arr_size) break; p_arr[ret++] = driver; } ns_release_iterator(&iter); return ret; }
int main (int argc, char *argv[]) { const bson_t *b; extent_t extent; record_t record; char *str; db_t db; ns_t ns; if (argc != 3) { fprintf(stderr, "usage: mdbdump DBPATH DBNAME\n"); return ARGC_FAILURE; } errno = 0; if (!!db_init(&db, argv[1], argv[2])) { perror("Failed to load database"); return DB_FAILURE; } errno = 0; if (!!db_namespaces(&db, &ns)) { perror("Failed to load namespaces"); return NS_FAILURE; } do { //fprintf(stdout, "\nNamespace \"%s\"\n\n", ns_name(&ns)); if (!!ns_extents(&ns, &extent)) { perror("Failed to load extent"); return EXTENT_FAILURE; } do { if (!extent_records(&extent, &record)) { do { b = record_bson(&record); if ((str = bson_as_json(b, NULL))) { puts(str); } bson_free(str); } while (!record_next(&record)); } } while (!extent_next(&extent)); } while (ns_next(&ns)); db_destroy(&db); return 0; }
static struct snobj *handle_reset_tcs(struct snobj *q) { struct ns_iter iter; struct tc *c; struct tc **c_arr; size_t arr_slots = 1024; int n = 0; c_arr = malloc(arr_slots * sizeof(struct tc *)); ns_init_iterator(&iter, NS_TYPE_TC); while ((c = (struct tc *)ns_next(&iter)) != NULL) { if (n >= arr_slots) { arr_slots *= 2; c_arr = realloc(c_arr, arr_slots * sizeof(struct tc *)); } c_arr[n] = c; n++; } ns_release_iterator(&iter); for (int i = 0; i < n; i++) { c = c_arr[i]; if (c->num_tasks) { free(c_arr); return snobj_err(EBUSY, "TC %s still has %d tasks", c->name, c->num_tasks); } if (c->auto_free) continue; tc_leave(c); tc_dec_refcnt(c); } free(c_arr); return NULL; }
/* * This function performs the actual IO, and must be called in a loop * (an event loop). Returns the current timestamp. */ time_t ns_mgr_poll(struct ns_mgr *mgr, int milli) { struct ns_connection *nc, *tmp; struct timeval tv; fd_set read_set, write_set, err_set; sock_t max_fd = INVALID_SOCKET; time_t current_time = time(NULL); FD_ZERO(&read_set); FD_ZERO(&write_set); FD_ZERO(&err_set); ns_add_to_set(mgr->ctl[1], &read_set, &max_fd); for (nc = mgr->active_connections; nc != NULL; nc = tmp) { tmp = nc->next; if (!(nc->flags & (NSF_LISTENING | NSF_CONNECTING))) { ns_call(nc, NS_POLL, ¤t_time); } /* * NS_POLL handler could have signaled us to close the connection * by setting NSF_CLOSE_IMMEDIATELY flag. In this case, we don't want to * trigger any other events on that connection, but close it right away. */ if (nc->flags & NSF_CLOSE_IMMEDIATELY) { /* NOTE(lsm): this call removes nc from the mgr->active_connections */ ns_close_conn(nc); continue; } if (!(nc->flags & NSF_WANT_WRITE)) { /*DBG(("%p read_set", nc)); */ ns_add_to_set(nc->sock, &read_set, &max_fd); } if (((nc->flags & NSF_CONNECTING) && !(nc->flags & NSF_WANT_READ)) || (nc->send_iobuf.len > 0 && !(nc->flags & NSF_CONNECTING) && !(nc->flags & NSF_BUFFER_BUT_DONT_SEND))) { /*DBG(("%p write_set", nc)); */ ns_add_to_set(nc->sock, &write_set, &max_fd); ns_add_to_set(nc->sock, &err_set, &max_fd); } } tv.tv_sec = milli / 1000; tv.tv_usec = (milli % 1000) * 1000; if (select((int) max_fd + 1, &read_set, &write_set, &err_set, &tv) > 0) { /* select() might have been waiting for a long time, reset current_time * now to prevent last_io_time being set to the past. */ current_time = time(NULL); /* Read wakeup messages */ if (mgr->ctl[1] != INVALID_SOCKET && FD_ISSET(mgr->ctl[1], &read_set)) { struct ctl_msg ctl_msg; int len = (int) recv(mgr->ctl[1], (char *) &ctl_msg, sizeof(ctl_msg), 0); send(mgr->ctl[1], ctl_msg.message, 1, 0); if (len >= (int) sizeof(ctl_msg.callback) && ctl_msg.callback != NULL) { struct ns_connection *c; for (c = ns_next(mgr, NULL); c != NULL; c = ns_next(mgr, c)) { ctl_msg.callback(c, NS_POLL, ctl_msg.message); } } } for (nc = mgr->active_connections; nc != NULL; nc = tmp) { tmp = nc->next; /* Windows reports failed connect() requests in err_set */ if (FD_ISSET(nc->sock, &err_set) && (nc->flags & NSF_CONNECTING)) { nc->last_io_time = current_time; ns_read_from_socket(nc); } if (FD_ISSET(nc->sock, &read_set)) { nc->last_io_time = current_time; if (nc->flags & NSF_LISTENING) { if (nc->flags & NSF_UDP) { ns_handle_udp(nc); } else { /* We're not looping here, and accepting just one connection at * a time. The reason is that eCos does not respect non-blocking * flag on a listening socket and hangs in a loop. */ accept_conn(nc); } } else { ns_read_from_socket(nc); } } if (FD_ISSET(nc->sock, &write_set)) { nc->last_io_time = current_time; if (nc->flags & NSF_CONNECTING) { ns_read_from_socket(nc); } else if (!(nc->flags & NSF_BUFFER_BUT_DONT_SEND) && !(nc->flags & NSF_CLOSE_IMMEDIATELY)) { ns_write_to_socket(nc); } } } } for (nc = mgr->active_connections; nc != NULL; nc = tmp) { tmp = nc->next; if ((nc->flags & NSF_CLOSE_IMMEDIATELY) || (nc->send_iobuf.len == 0 && (nc->flags & NSF_FINISHED_SENDING_DATA))) { ns_close_conn(nc); } } return current_time; }
static struct snobj *handle_list_tcs(struct snobj *q) { struct snobj *r; struct snobj *t; unsigned int wid_filter = MAX_WORKERS; struct ns_iter iter; struct tc *c; t = snobj_eval(q, "wid"); if (t) { wid_filter = snobj_uint_get(t); if (wid_filter >= MAX_WORKERS) return snobj_err(EINVAL, "'wid' must be between 0 and %d", MAX_WORKERS - 1); if (!is_worker_active(wid_filter)) return snobj_err(EINVAL, "worker:%d does not exist", wid_filter); } r = snobj_list(); ns_init_iterator(&iter, NS_TYPE_TC); while ((c = (struct tc *)ns_next(&iter)) != NULL) { int wid; if (wid_filter < MAX_WORKERS) { if (workers[wid_filter]->s != c->s) continue; wid = wid_filter; } else { for (wid = 0; wid < MAX_WORKERS; wid++) if (is_worker_active(wid) && workers[wid]->s == c->s) break; } struct snobj *elem = snobj_map(); snobj_map_set(elem, "name", snobj_str(c->name)); snobj_map_set(elem, "tasks", snobj_int(c->num_tasks)); snobj_map_set(elem, "parent", snobj_str(c->parent->name)); snobj_map_set(elem, "priority", snobj_int(c->priority)); if (wid < MAX_WORKERS) snobj_map_set(elem, "wid", snobj_uint(wid)); else snobj_map_set(elem, "wid", snobj_int(-1)); snobj_list_add(r, elem); } ns_release_iterator(&iter); return r; }