//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //module_shutdown //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int module_shutdown() { listnode *ln, *ln2; //Destroy contained controls dolist (ln2, globalmodule.controllist_parentsonly) control_destroy((control *) ln2->value, false, false); dolist (ln, modulelist) { module *m = (module *) ln->value; if (m->enabled) dolist (ln2, m->controllist_parentsonly) control_destroy((control *) ln2->value, false, false); }
void sml_run_toplevels(void (**topfuncs)(void)) { struct frame_stack_range dummy_range = {.top = NULL, .bottom = NULL}; struct sml_control *control = tlv_get_or_init(current_control); if (control != NULL) { for (; *topfuncs; topfuncs++) (*topfuncs)(); return; } /* Set up a control block with a dummy stack range. * This avoids frequent allocation and deallocation of thread local * heap due to sml_start and sml_end called at the beginning and end * of each top-level fragment. */ control = control_start(&dummy_range); control_leave(control); for (; *topfuncs; topfuncs++) (*topfuncs)(); /* NOTE: if an uncaught exception occurs, the following code will * not be executed. */ control_enter(control); assert(control->frame_stack == &dummy_range); control_destroy(control); }
static void thread_cancelled(struct sml_control *control) { /* This function is called with a non-NULL control if an SML# thread * is cancelled abnormally, for example, due to pthread_cancel or * pthread_exit. Since SML# code never cancel any thread, a thread * may be cancelled only in C code (pthread provides asynchronous * cancellation, but no clever programmer use it ;p). Therefore, * the current thread does not occupy its sml_control at the * beginning of this function. * Note that tlv_get(current_control) is NULL due to thread exit. */ if (!control) return; /* recover tlv_get(control) temporarily for thread local heap * deallocation */ tlv_set(current_control, control); /* occupy the control to deallocate the thread local heap safely */ control_enter(control); /* control_destroy resets tlv_get(control) to NULL. * This avoids iteration of destructor calls. */ control_destroy(control); }
int main(int argc, char *argv[]) { int num; struct control *c; struct control_dependency *cd; struct control_source *cs; if ((num = parse_params(argc, argv)) < 0) { fprintf(stderr, "Usage: pkgcontrol [COMMAND] FILES...\n"); fprintf(stderr, "Commands:\n"); fprintf(stderr, " -n: Dump package name\n"); fprintf(stderr, " -v: Dump package version\n"); fprintf(stderr, " -r: Dump package runtime dependencies\n"); fprintf(stderr, " -b: Dump package build dependencies\n"); fprintf(stderr, " -s: Dump package sources\n"); return EXIT_FAILURE; } for (; num < argc; num++) { if (control_parse(argv[num], &c) != 0) { fprintf(stderr, "Error parsing '%s'\n", argv[num]); return EXIT_FAILURE; } switch (field) { case FIELD_NAME: puts(c->package); break; case FIELD_VERSION: puts(c->version); break; case FIELD_DEP_RUN: for (cd = c->run_depend; cd != NULL; cd = cd->next) { puts(cd->package); } break; case FIELD_DEP_BUILD: for (cd = c->build_depend; cd != NULL; cd = cd->next) { puts(cd->package); } break; case FIELD_SRCS: for (cs = c->sources; cs != NULL; cs = cs->next) { puts(cs->source); } break; default: break; } control_destroy(c); } return 0; }
void initialize_structs(void) { numthreads=0; if (control_init(&wq.control)) dabort(); queue_init(&wq.work); if (control_init(&cq.control)) { control_destroy(&wq.control); dabort(); } queue_init(&wq.work); control_activate(&wq.control); }
void erase_ncs() { control_destroy(active_ncs->c); --num_ncs; memcpy(active_ncs, ncss[num_ncs], sizeof(control*)); ncss = realloc(ncss, sizeof(control*) * num_ncs); active_ncs = 0; active_pt = 0; }
void main_loop_deinit(void) { main_loop_free_config(); if (!syntax_only) control_destroy(); iv_event_unregister(&exit_requested); iv_event_unregister(&reload_config_requested); main_loop_call_deinit(); main_loop_io_worker_deinit(); main_loop_worker_deinit(); }
SML_PRIMITIVE void sml_end() { struct sml_control *control = tlv_get(current_control); #ifndef WITHOUT_MULTITHREAD assert(IS_ACTIVE(load_relaxed(&control->state))); #endif /* !WITHOUT_MULTITHREAD */ assert(control->frame_stack->bottom == CALLER_FRAME_END_ADDRESS()); control->frame_stack = control->frame_stack->next; if (control->frame_stack) { control_leave(control); } else { control_destroy(control); } }
void cleanup_structs(void) { control_destroy(&cq.control); control_destroy(&wq.control); }
/** * @brief free resources used by a connection * @param c the connection to free * * all connection threads and owned childs must be ended before this call, * otherwise they will access to free'd memory. */ void free_connection(conn_node *c) { control_destroy(&(c->control)); control_destroy(&(c->incoming.control)); control_destroy(&(c->outcoming.control)); free(c); }
/** * @brief destroy lists controls */ void destroy_structs() { control_destroy(&(connections.control)); control_destroy(&(graveyard.control)); }