PUSS_EXPORT void* puss_plugin_create(Puss* app) { GTree* sections; GtkSourceLanguageManager* lm; const gchar* const* ids; const gchar* const* id; GtkSourceLanguage* lang; const gchar* name; gchar* action_name; GtkAction* action; const gchar* section; GList* section_list; GtkUIManager* ui_mgr; IToolMenuAction* tool_menu_interface; GString* gstr; gchar* ui_info; GError* err; tool_menu_interface = app->extend_query("puss_controls", INTERFACE_TOOL_MENU_ACTION); if( !tool_menu_interface ) return 0; bindtextdomain(TEXT_DOMAIN, app->get_locale_path()); bind_textdomain_codeset(TEXT_DOMAIN, "UTF-8"); g_self = g_new0(LanguageSelector, 1); g_self->app = app; g_self->action_group = gtk_action_group_new("puss_language_selector_action_group"); // set select language menu sections = g_tree_new_full((GCompareDataFunc)&g_ascii_strcasecmp, 0, 0, (GDestroyNotify)g_list_free); lm = gtk_source_language_manager_get_default(); ids = gtk_source_language_manager_get_language_ids(lm); g_self->last_favory_lang = gtk_source_language_manager_get_language(lm, "cpp"); for( id=ids; *id; ++id ) { lang = gtk_source_language_manager_get_language(lm, *id); if( lang ) { name = gtk_source_language_get_name(lang); action_name = g_strdup_printf("pls_lang_%s", name); action = gtk_action_new(action_name, name, NULL, NULL); g_signal_connect(action, "activate", G_CALLBACK(&pls_lang_active), lang); gtk_action_group_add_action(g_self->action_group, action); g_object_unref(action); g_free(action_name); section = gtk_source_language_get_section(lang); section_list = (GList*)g_tree_lookup(sections, section); if( section_list ) { g_tree_steal(sections, section); } else { action_name = g_strdup_printf("pls_sec_%s", section); action = GTK_ACTION(gtk_action_new(action_name, section, NULL, NULL)); gtk_action_group_add_action(g_self->action_group, action); g_object_unref(action); g_free(action_name); } section_list = g_list_insert_sorted(section_list, (gchar*)name, (GCompareFunc)&g_ascii_strcasecmp); g_tree_insert(sections, (gchar*)section, section_list); } } // insert language selector menu-tool-button // action = gtk_action_new("language_selector_open", _("Language"), _("select high-light source language, default use last"), GTK_STOCK_SELECT_COLOR); gtk_action_group_add_action(g_self->action_group, action); g_object_unref(action); action = GTK_ACTION( g_object_new(tool_menu_interface->get_type () , "name", "language_selector_toolmenu_open" , "label", _("Language") , "tooltip", _("select high-light source language, default use last") , "stock-id", GTK_STOCK_SELECT_COLOR , NULL) ); g_signal_connect(action, "activate", G_CALLBACK(&pls_lang_active), 0); gtk_action_group_add_action(g_self->action_group, action); g_object_unref(action); ui_mgr = GTK_UI_MANAGER(gtk_builder_get_object(app->get_ui_builder(), "main_ui_manager")); gtk_ui_manager_insert_action_group(ui_mgr, g_self->action_group, 0); // main selector menu gstr= g_string_new(NULL); g_tree_foreach(sections, (GTraverseFunc)&fill_language_section, gstr); g_tree_destroy(sections); ui_info = g_strdup_printf( "<ui>" " <menubar name='main_menubar'>" " <menu action='view_menu'>\n" " <placeholder name='view_menu_extend_place'>" " <menu action='language_selector_open'>" " %s" " <placeholder name='pls_favory_menu_place'>" " </placeholder>" " </menu>" " </placeholder>" " </menu>" " </menubar>" "" " <toolbar name='main_toolbar'>" " <placeholder name='main_toolbar_view_place'>" " <toolitem action='language_selector_toolmenu_open'>" " <menu action='language_selector_toolmenu_open'>" " %s" " <placeholder name='pls_favory_toolmenu_place'>" " </placeholder>" " </menu>" " </toolitem>" " </placeholder>" " </toolbar>" "</ui>" , gstr->str , gstr->str ); //g_print(ui_info); err = 0; g_self->merge_id = gtk_ui_manager_add_ui_from_string(ui_mgr, ui_info, -1, &err); if( err ) { g_printerr("%s", err->message); g_error_free(err); } g_free(ui_info); g_string_free(gstr, TRUE); gtk_ui_manager_ensure_update(ui_mgr); fill_favory_language_menu(); return g_self; }
static int edit_read_syntax_rules (WEdit * edit, FILE * f, char **args, int args_size) { FILE *g = NULL; char *fg, *bg, *attrs; char last_fg[32] = "", last_bg[32] = "", last_attrs[64] = ""; char whole_right[512]; char whole_left[512]; char *l = 0; int save_line = 0, line = 0; struct context_rule **r, *c = NULL; int num_words = -1, num_contexts = -1; int result = 0; int argc; int i, j; int alloc_contexts = MAX_CONTEXTS, alloc_words_per_context = MAX_WORDS_PER_CONTEXT, max_alloc_words_per_context = MAX_WORDS_PER_CONTEXT; args[0] = NULL; edit->is_case_insensitive = FALSE; strcpy (whole_left, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890"); strcpy (whole_right, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_01234567890"); r = edit->rules = g_malloc0 (alloc_contexts * sizeof (struct context_rule *)); if (!edit->defines) edit->defines = g_tree_new ((GCompareFunc) strcmp); for (;;) { char **a; size_t len; line++; l = 0; len = read_one_line (&l, f); if (len == 0) { if (g) { fclose (f); f = g; g = 0; line = save_line + 1; MC_PTR_FREE (error_file_name); MC_PTR_FREE (l); len = read_one_line (&l, f); if (len == 0) break; else xx_lowerize_line (edit, l, len); } else { break; } } else { xx_lowerize_line (edit, l, len); } argc = get_args (l, args, args_size); a = args + 1; if (!args[0]) { /* do nothing */ } else if (!strcmp (args[0], "include")) { if (g || argc != 2) { result = line; break; } g = f; f = open_include_file (args[1]); if (!f) { MC_PTR_FREE (error_file_name); result = line; break; } save_line = line; line = 0; } else if (!strcmp (args[0], "caseinsensitive")) { edit->is_case_insensitive = TRUE; } else if (!strcmp (args[0], "wholechars")) { check_a; if (!strcmp (*a, "left")) { a++; g_strlcpy (whole_left, *a, sizeof (whole_left)); } else if (!strcmp (*a, "right")) { a++; g_strlcpy (whole_right, *a, sizeof (whole_right)); } else { g_strlcpy (whole_left, *a, sizeof (whole_left)); g_strlcpy (whole_right, *a, sizeof (whole_right)); } a++; check_not_a; } else if (!strcmp (args[0], "context")) { check_a; if (num_contexts == -1) { if (strcmp (*a, "default")) { /* first context is the default */ break_a; } a++; c = r[0] = g_malloc0 (sizeof (struct context_rule)); c->left = g_strdup (" "); c->right = g_strdup (" "); num_contexts = 0; } else { /* Terminate previous context. */ r[num_contexts - 1]->keyword[num_words] = NULL; c = r[num_contexts] = g_malloc0 (sizeof (struct context_rule)); if (!strcmp (*a, "exclusive")) { a++; c->between_delimiters = 1; } check_a; if (!strcmp (*a, "whole")) { a++; c->whole_word_chars_left = g_strdup (whole_left); c->whole_word_chars_right = g_strdup (whole_right); } else if (!strcmp (*a, "wholeleft")) { a++; c->whole_word_chars_left = g_strdup (whole_left); } else if (!strcmp (*a, "wholeright")) { a++; c->whole_word_chars_right = g_strdup (whole_right); } check_a; if (!strcmp (*a, "linestart")) { a++; c->line_start_left = 1; } check_a; c->left = g_strdup (*a++); check_a; if (!strcmp (*a, "linestart")) { a++; c->line_start_right = 1; } check_a; c->right = g_strdup (*a++); c->first_left = *c->left; c->first_right = *c->right; } c->keyword = g_malloc (alloc_words_per_context * sizeof (struct key_word *)); num_words = 1; c->keyword[0] = g_malloc0 (sizeof (struct key_word)); subst_defines (edit->defines, a, &args[1024]); fg = *a; if (*a) a++; bg = *a; if (*a) a++; attrs = *a; if (*a) a++; g_strlcpy (last_fg, fg ? fg : "", sizeof (last_fg)); g_strlcpy (last_bg, bg ? bg : "", sizeof (last_bg)); g_strlcpy (last_attrs, attrs ? attrs : "", sizeof (last_attrs)); c->keyword[0]->color = this_try_alloc_color_pair (fg, bg, attrs); c->keyword[0]->keyword = g_strdup (" "); check_not_a; alloc_words_per_context = MAX_WORDS_PER_CONTEXT; if (++num_contexts >= alloc_contexts) { struct context_rule **tmp; alloc_contexts += 128; tmp = g_realloc (r, alloc_contexts * sizeof (struct context_rule *)); r = tmp; } } else if (!strcmp (args[0], "spellcheck")) { if (!c) { result = line; break; } c->spelling = 1; } else if (!strcmp (args[0], "keyword")) { struct key_word *k; if (num_words == -1) break_a; check_a; k = r[num_contexts - 1]->keyword[num_words] = g_malloc0 (sizeof (struct key_word)); if (!strcmp (*a, "whole")) { a++; k->whole_word_chars_left = g_strdup (whole_left); k->whole_word_chars_right = g_strdup (whole_right); } else if (!strcmp (*a, "wholeleft")) { a++; k->whole_word_chars_left = g_strdup (whole_left); } else if (!strcmp (*a, "wholeright")) { a++; k->whole_word_chars_right = g_strdup (whole_right); } check_a; if (!strcmp (*a, "linestart")) { a++; k->line_start = 1; } check_a; if (!strcmp (*a, "whole")) { break_a; } k->keyword = g_strdup (*a++); k->first = *k->keyword; subst_defines (edit->defines, a, &args[1024]); fg = *a; if (*a) a++; bg = *a; if (*a) a++; attrs = *a; if (*a) a++; if (!fg) fg = last_fg; if (!bg) bg = last_bg; if (!attrs) attrs = last_attrs; k->color = this_try_alloc_color_pair (fg, bg, attrs); check_not_a; if (++num_words >= alloc_words_per_context) { struct key_word **tmp; alloc_words_per_context += 1024; if (alloc_words_per_context > max_alloc_words_per_context) max_alloc_words_per_context = alloc_words_per_context; tmp = g_realloc (c->keyword, alloc_words_per_context * sizeof (struct key_word *)); c->keyword = tmp; } } else if (*(args[0]) == '#') { /* do nothing for comment */ } else if (!strcmp (args[0], "file")) { break; } else if (!strcmp (args[0], "define")) { char *key = *a++; char **argv; if (argc < 3) break_a; argv = g_tree_lookup (edit->defines, key); if (argv != NULL) mc_defines_destroy (NULL, argv, NULL); else key = g_strdup (key); argv = g_new (char *, argc - 1); g_tree_insert (edit->defines, key, argv); while (*a != NULL) { *argv++ = g_strdup (*a++); } *argv = NULL; } else { /* anything else is an error */
static event_response_t cb(drakvuf_t drakvuf, drakvuf_trap_info_t* info) { poolmon* p = (poolmon*)info->trap->data; page_mode_t pm = drakvuf_get_page_mode(drakvuf); reg_t pool_type, size; char tag[5] = { [0 ... 4] = '\0' }; struct pooltag* s = NULL; const char* pool_type_str; access_context_t ctx; ctx.translate_mechanism = VMI_TM_PROCESS_DTB; ctx.dtb = info->regs->cr3; if (pm == VMI_PM_IA32E) { pool_type = info->regs->rcx; size = info->regs->rdx; *(reg_t*)tag = info->regs->r8; } else { vmi_lock_guard vmi_lg(drakvuf); vmi_instance_t& vmi = vmi_lg.vmi; ctx.addr = info->regs->rsp+12; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)tag) ) return 0; ctx.addr = info->regs->rsp+8; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)&size) ) return 0; ctx.addr = info->regs->rsp+4; if ( VMI_FAILURE == vmi_read_32(vmi, &ctx, (uint32_t*)&pool_type) ) return 0; } s = (struct pooltag*)g_tree_lookup(p->pooltag_tree, tag); pool_type_str = pool_type<MaxPoolType ? pool_types[pool_type] : "unknown_pool_type"; switch (p->format) { case OUTPUT_CSV: printf("poolmon," FORMAT_TIMEVAL ",%" PRIu32 ",0x%" PRIx64 ",\"%s\",%" PRIi64 ",%s,%s,%" PRIu64 "", UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, info->proc_data.name, info->proc_data.userid, tag, pool_type_str, size); if (s) printf(",%s,%s", s->source, s->description); break; case OUTPUT_KV: printf("poolmon Time=" FORMAT_TIMEVAL ",PID=%d,PPID=%d,ProcessName=\"%s\"," "Tag=%s,Type=%s,Size=%" PRIu64, UNPACK_TIMEVAL(info->timestamp), info->proc_data.pid, info->proc_data.ppid, info->proc_data.name, tag, pool_type_str, size); if (s) printf(",Source=%s,Description=%s", s->source, s->description); break; default: case OUTPUT_DEFAULT: printf("[POOLMON] TIME:" FORMAT_TIMEVAL " VCPU:%" PRIu32 " CR3:0x%" PRIx64 ",\"%s\" %s:%" PRIi64 " %s (type: %s, size: %" PRIu64 ")", UNPACK_TIMEVAL(info->timestamp), info->vcpu, info->regs->cr3, info->proc_data.name, USERIDSTR(drakvuf), info->proc_data.userid, tag, pool_type_str, size); if (s) printf(": %s,%s", s->source, s->description); break; } printf("\n"); return 0; }
int BLEIO_gatt_read_char_by_uuid( BLEIO_GATT_HANDLE bleio_gatt_handle, const char* ble_uuid, ON_BLEIO_GATT_ATTRIB_READ_COMPLETE on_bleio_gatt_attrib_read_complete, void* callback_context ) { int result; BLEIO_GATT_HANDLE_DATA* handle_data = (BLEIO_GATT_HANDLE_DATA*)bleio_gatt_handle; /*Codes_SRS_BLEIO_GATT_13_027: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if bleio_gatt_handle is NULL. ]*/ /*Codes_SRS_BLEIO_GATT_13_028: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if on_bleio_gatt_attrib_read_complete is NULL. ]*/ /*Codes_SRS_BLEIO_GATT_13_051: [BLEIO_gatt_read_char_by_uuid shall return a non - zero value if ble_uuid is NULL. ] */ /*Codes_SRS_BLEIO_GATT_13_052: [BLEIO_gatt_read_char_by_uuid shall return a non - zero value if the object is not in a connected state. ] */ if ( bleio_gatt_handle != NULL && ble_uuid != NULL && on_bleio_gatt_attrib_read_complete != NULL && handle_data->state == BLEIO_GATT_STATE_CONNECTED ) { GString* uuid = g_string_new(ble_uuid); if(uuid != NULL) { GString* object_path = g_tree_lookup(handle_data->char_object_path_map, uuid); if(object_path != NULL) { // now that we have the object path we don't need the UUID anymore g_string_free(uuid, TRUE); READ_CONTEXT *context = (READ_CONTEXT *)malloc(sizeof(READ_CONTEXT)); if (context != NULL) { // create async sequence context->async_seq = GIO_Async_Seq_Create( context, on_sequence_error, on_sequence_complete ); if (context->async_seq != NULL) { // setup call sequence GIO_ASYNCSEQ_RESULT seq_result = GIO_Async_Seq_Add( context->async_seq, NULL, // create an instance of the characteristic create_characteristic, create_characteristic_finish, // read the characteristic read_characteristic, read_characteristic_finish, // sentinel value to signal end of sequence NULL ); if (seq_result == GIO_ASYNCSEQ_OK) { context->handle_data = handle_data; context->object_path = object_path; context->characteristic = NULL; context->on_read_complete = on_bleio_gatt_attrib_read_complete; context->callback_context = callback_context; /*Codes_SRS_BLEIO_GATT_13_031: [ BLEIO_gatt_read_char_by_uuid shall asynchronously initiate a read characteristic operation using the specified UUID. ]*/ // kick-off the sequence if(GIO_Async_Seq_Run_Async(context->async_seq) == GIO_ASYNCSEQ_OK) { /*Codes_SRS_BLEIO_GATT_13_030: [ BLEIO_gatt_read_char_by_uuid shall return 0 (zero) if the read characteristic operation is successful. ]*/ result = 0; } else { result = __LINE__; GIO_Async_Seq_Destroy(context->async_seq); free(context); LogError("GIO_Async_Seq_Run failed."); } } else { /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/ result = __LINE__; GIO_Async_Seq_Destroy(context->async_seq); free(context); LogError("GIO_Async_Seq_Add failed."); } } else { /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/ result = __LINE__; free(context); LogError("GIO_Async_Seq_Create failed."); } } else { /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/ result = __LINE__; LogError("malloc failed."); } } else { /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/ result = __LINE__; g_string_free(uuid, TRUE); LogError("g_tree_lookup() failed."); } } else { /*Codes_SRS_BLEIO_GATT_13_029: [ BLEIO_gatt_read_char_by_uuid shall return a non-zero value if an underlying platform call fails. ]*/ result = __LINE__; LogError("g_string_new() failed."); } } else { result = __LINE__; LogError("Invalid args or the state of the object is unexpected."); } return result; }
//--------------------------------------------------------------------------------------// void Http_getMailboxes(T R) { const char *mailbox = Request_getId(R); TRACE(TRACE_DEBUG,"mailbox [%s]", mailbox); char *endptr = NULL; struct evbuffer *buf; u64_t id = 0; if (! mailbox) { Request_error(R, HTTP_SERVUNAVAIL, "Server error"); return; } if (! (id = strtoull(mailbox, &endptr, 10))) { Request_error(R, HTTP_NOTFOUND, "Not found"); return; } TRACE(TRACE_DEBUG,"mailbox id [%llu]", id); buf = evbuffer_new(); Request_setContentType(R,"application/json; charset=utf-8"); if (Request_getMethod(R) == NULL) { /* * retrieve mailbox meta-data * C < GET /mailboxes/876 * * or * * append a new message * C < POST /mailboxes/876 */ const char *msg; u64_t msg_id = 0; MailboxState_T b = MailboxState_new(id); unsigned exists = MailboxState_getExists(b); if ((msg = evhttp_find_header(Request_getPOST(R),"message"))) { if (! db_append_msg(msg, MailboxState_getId(b), MailboxState_getOwner(b), NULL, &msg_id, TRUE)) exists++; } evbuffer_add_printf(buf, "{\"mailboxes\": {\n"); evbuffer_add_printf(buf, " \"%llu\":{\"name\":\"%s\",\"exists\":%d}", MailboxState_getId(b), MailboxState_getName(b), exists); evbuffer_add_printf(buf, "\n}}\n"); MailboxState_free(&b); } else if (MATCH(Request_getMethod(R),"messages")) { /* * list messages in mailbox * C < GET /mailboxes/876/messages */ MailboxState_T b = MailboxState_new(id); GTree *msns = MailboxState_getMsn(b); GList *ids = g_tree_keys(msns); GTree *msginfo = MailboxState_getMsginfo(b); evbuffer_add_printf(buf, "{\"messages\": {\n"); while (ids && ids->data) { u64_t *msn = (u64_t *)ids->data; u64_t *uid = (u64_t *)g_tree_lookup(msns, msn); MessageInfo *info = (MessageInfo *)g_tree_lookup(msginfo, uid); evbuffer_add_printf(buf, " \"%llu\":{\"size\":%llu}", *uid, info->rfcsize); if (! g_list_next(ids)) break; ids = g_list_next(ids); evbuffer_add_printf(buf,",\n"); } evbuffer_add_printf(buf, "\n}}\n"); if (ids) g_list_free(g_list_first(ids)); MailboxState_free(&b); } if (EVBUFFER_LENGTH(buf)) Request_send(R, HTTP_OK, "OK", buf); else Request_error(R, HTTP_SERVUNAVAIL, "Server error"); evbuffer_free(buf); }
static gint sqlx_lookup_id(sqlx_cache_t *cache, const hashstr_t *hs) { gpointer lookup_result = g_tree_lookup(cache->bases_by_name, hs); return !lookup_result ? -1 : (GPOINTER_TO_INT(lookup_result) - 1); }
void rpc_service_handle(rpc_service_t *service, zmq_msg_t *request) { /* Parse the msgpack */ zmq_msg_t response; int rc; msgpack_unpacked request_msg; msgpack_unpacked_init(&request_msg); rc = msgpack_unpack_next(&request_msg, zmq_msg_data(request), zmq_msg_size(request), NULL); insist_return(rc, (void)(0), "Failed to unpack message '%.*s'", (int)zmq_msg_size(request), (char *)zmq_msg_data(request)); msgpack_object request_obj = request_msg.data; /* Find the method name */ char *method = NULL; size_t method_len = -1; rc = obj_get(&request_obj, "method", MSGPACK_OBJECT_RAW, &method, &method_len); msgpack_sbuffer *response_buffer = msgpack_sbuffer_new(); msgpack_sbuffer *result_buffer = msgpack_sbuffer_new(); msgpack_sbuffer *error_buffer = msgpack_sbuffer_new(); msgpack_packer *response_msg = msgpack_packer_new(response_buffer, msgpack_sbuffer_write); msgpack_packer *result = msgpack_packer_new(result_buffer, msgpack_sbuffer_write); msgpack_packer *error = msgpack_packer_new(error_buffer, msgpack_sbuffer_write); //printf("Method: %.*s\n", method_len, method); void *clock = zmq_stopwatch_start(); double duration; if (rc != 0) { /* method not found */ msgpack_pack_nil(result); /* result is nil on error */ msgpack_pack_map(error, 2); msgpack_pack_string(error, "error", -1); msgpack_pack_string(error, "Message had no 'method' field", -1); msgpack_pack_string(error, "request", -1); msgpack_pack_object(error, request_obj); } else { /* valid method, keep going */ //printf("The method is: '%.*s'\n", (int)method_len, method); rpc_name name; name.name = method; name.len = method_len; rpc_method *rpcmethod = g_tree_lookup(service->methods, &name); /* if we found a valid rpc method and the args check passed ... */ if (rpcmethod != NULL) { /* the callback is responsible for filling in the 'result' and 'error' * objects. */ rpcmethod->callback(NULL, &request_obj, result, error, rpcmethod->data); } else { msgpack_pack_nil(result); /* result is nil on error */ /* TODO(sissel): allow methods to register themselves */ //fprintf(stderr, "Invalid request '%.*s' (unknown method): ", //method_len, method); //msgpack_object_print(stderr, request_obj); //fprintf(stderr, "\n"); msgpack_pack_map(error, 2); msgpack_pack_string(error, "error", -1); msgpack_pack_string(error, "No such method requested", -1); msgpack_pack_string(error, "request", -1); msgpack_pack_object(error, request_obj); } } /* valid/invalid method handling */ duration = zmq_stopwatch_stop(clock) / 1000000.; //printf("method '%.*s' took %lf seconds\n", (int)method_len, method); msgpack_unpacked result_unpacked; msgpack_unpacked error_unpacked; msgpack_unpacked response_unpacked; msgpack_unpacked_init(&result_unpacked); msgpack_unpacked_init(&error_unpacked); msgpack_unpacked_init(&response_unpacked); /* TODO(sissel): If this unpack test fails, we should return an error to the calling * client indicating that some internal error has occurred */ //fprintf(stderr, "Result payload: '%.*s'\n", result_buffer->size, //result_buffer->data); rc = msgpack_unpack_next(&result_unpacked, result_buffer->data, result_buffer->size, NULL); insist(rc == true, "msgpack_unpack_next failed on 'result' buffer" " of request '%.*s'", (int)method_len, method); rc = msgpack_unpack_next(&error_unpacked, error_buffer->data, error_buffer->size, NULL); insist(rc == true, "msgpack_unpack_next failed on 'error' buffer" " of request '%.*s'", (int)method_len, method); msgpack_pack_map(response_msg, 3); /* result, error, duration */ msgpack_pack_string(response_msg, "result", 6); msgpack_pack_object(response_msg, result_unpacked.data); msgpack_pack_string(response_msg, "error", 5); msgpack_pack_object(response_msg, error_unpacked.data); msgpack_pack_string(response_msg, "duration", 8); msgpack_pack_double(response_msg, duration); rc = msgpack_unpack_next(&response_unpacked, response_buffer->data, response_buffer->size, NULL); insist(rc == true, "msgpack_unpack_next failed on full response buffer" " of request '%.*s'", (int)method_len, method); //printf("request: "); //msgpack_object_print(stdout, request_obj); //printf("\n"); //printf("response: "); //msgpack_object_print(stdout, response_unpacked.data); //printf("\n"); zmq_msg_init_data(&response, response_buffer->data, response_buffer->size, free_msgpack_buffer, response_buffer); zmq_send(service->socket, &response, 0); zmq_msg_close(&response); msgpack_packer_free(error); msgpack_packer_free(result); msgpack_sbuffer_free(error_buffer); msgpack_sbuffer_free(result_buffer); msgpack_packer_free(response_msg); msgpack_unpacked_destroy(&request_msg); } /* rpc_service_handle */
/** * @brief Function that will run the thread associated with a particular interface * instance. * * Since multiple different command line a graphical user interfaces * can exists simultaneously, this allows the scheduler to quickly perform any * requests. * * Handle commands: * * | Command | Description | * | ---: | :--- | * | exit | Close connection with scheduler | * | kill | Kill a particular job | * | load | Get the host status | * | close | Shutdown the scheduler | * | pause | Pause a job that is currently running | * | reload | Reload configuration information | * | status | Request status for scheduler or job | * | restart | Restart a paused job | * | verbose | Change verbose level for scheduler or job | * | priority | Change the priority of job | * | database | Check the database job queue | * * @param conn Pointer to the interface_connection structure * @param scheduler Pointer to the relevant scheduler structure * @return not currently used */ void interface_thread(interface_connection* conn, scheduler_t* scheduler) { GMatchInfo* regex_match; job_t* job; char buffer[BUFFER_SIZE]; char org[sizeof(buffer)]; char* arg1, * arg2, * arg3; char* cmd; arg_int* params; int i; memset(buffer, '\0', sizeof(buffer)); while(g_input_stream_read(conn->istr, buffer, sizeof(buffer), scheduler->cancel, NULL) > 0) { V_INTERFACE("INTERFACE: received \"%s\"\n", buffer); /* convert all characters before first ' ' to lower case */ memcpy(org, buffer, sizeof(buffer)); for(cmd = buffer; *cmd; cmd++) *cmd = g_ascii_tolower(*cmd); g_regex_match(scheduler->parse_interface_cmd, buffer, 0, ®ex_match); cmd = g_match_info_fetch(regex_match, 1); if(cmd == NULL) { g_output_stream_write(conn->ostr, "Invalid command: \"", 18, NULL, NULL); g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL); g_output_stream_write(conn->ostr, "\"\n", 2, NULL, NULL); g_match_info_free(regex_match); WARNING("INTERFACE: invalid command: \"%s\"", buffer); continue; } /* acknowledge that you have received the command */ V_INTERFACE("INTERFACE: send \"received\"\n"); g_output_stream_write(conn->ostr, "received\n", 9, NULL, NULL); /* command: "close" * * The interface has chosen to close the connection. Return the command * in acknowledgment of the command and end this thread. */ if(strcmp(cmd, "close") == 0) { g_output_stream_write(conn->ostr, "CLOSE\n", 6, NULL, NULL); V_INTERFACE("INTERFACE: closing connection to user interface\n"); g_match_info_free(regex_match); g_free(cmd); return; } /* command: "stop" * * The interface has instructed the scheduler to shut down gracefully. The * scheduler will wait for all currently executing agents to finish * running, then exit the vent loop. */ else if(strcmp(cmd, "stop") == 0) { g_output_stream_write(conn->ostr, "CLOSE\n", 6, NULL, NULL); V_INTERFACE("INTERFACE: shutting down scheduler gracefully\n"); event_signal(scheduler_close_event, (void*)0); g_match_info_free(regex_match); g_free(cmd); return; } /* command: "die" * * The interface has instructed the scheduler to shut down. The scheduler * should acknowledge the command and proceed to kill all current executing * agents and exit the event loop */ else if(strcmp(cmd, "die") == 0) { g_output_stream_write(conn->ostr, "CLOSE\n", 6, NULL, NULL); V_INTERFACE("INTERFACE: killing the scheduler\n"); event_signal(scheduler_close_event, (void*)1); g_match_info_free(regex_match); g_free(cmd); return; } /* command: "load" * * The interface has requested information about the load that the different * hosts are under. The scheduler should respond with the status of all the * hosts. */ else if(strcmp(cmd, "load") == 0) { print_host_load(scheduler->host_list, conn->ostr); } /* command: "kill <job_id> <"message">" * * The interface has instructed the scheduler to kill and fail a particular * job. Both arguments are required for this command. * * job_id: The jq_pk for the job that needs to be killed * message: A message that will be in the email notification and the * jq_endtext field of the job queue */ else if(strcmp(cmd, "kill") == 0) { arg1 = g_match_info_fetch(regex_match, 3); arg2 = g_match_info_fetch(regex_match, 8); if(arg1) i = atoi(arg1); if(arg1 == NULL || arg2 == NULL || strlen(arg1) == 0 || strlen(arg2) == 0) { g_free(cmd); cmd = g_strdup_printf("Invalid kill command: \"%s\"\n", buffer); g_output_stream_write(conn->ostr, cmd, strlen(cmd), NULL, NULL); } else if((job = g_tree_lookup(scheduler->job_list, &i)) == NULL) { arg3 = g_strdup_printf(jobsql_failed, arg2, i); event_signal(database_exec_event, arg3); } else { if(job->message) g_free(job->message); job->message = strdup(((arg2 == NULL) ? "no message" : arg2)); event_signal(job_fail_event, job); } g_free(arg1); g_free(arg2); } /* command: "pause <job_id>" * * The interface has instructed the scheduler to pause a job. This is used * to free up resources on a particular host. The argument is required and * is the jq_pk for the job that needs to be paused. */ else if(strcmp(cmd, "pause") == 0) { arg1 = g_match_info_fetch(regex_match, 3); if(arg1 == NULL || strlen(arg1) == 0) { arg1 = g_strdup_printf("Invalid pause command: \"%s\"\n", buffer); WARNING("received invalid pause command: %s", buffer); g_output_stream_write(conn->ostr, arg1, strlen(arg1), NULL, NULL); g_free(arg1); } else { params = g_new0(arg_int, 1); params->second = atoi(arg1); params->first = g_tree_lookup(scheduler->job_list, ¶ms->second); event_signal(job_pause_event, params); g_free(arg1); } } /* command: "reload" * * The scheduler should reload its configuration information. This should * be used if a change to an agent or fossology.conf has been made since * the scheduler started running. */ else if(strcmp(cmd, "reload") == 0) { event_signal(scheduler_config_event, NULL); } /* command: "agents" * * The interface has requested a list of agents that the scheduler is able * to run correctly. */ else if(strcmp(cmd, "agents") == 0) { event_signal(list_agents_event, conn->ostr); } /* command: "status [job_id]" * * fetches the status of the a particular job or the scheduler. The * argument is not required for this command. * * with job_id: * print job status followed by status of agent belonging to the job * without job_id: * print scheduler statsu followed by status of every job */ else if(strcmp(cmd, "status") == 0) { arg1 = g_match_info_fetch(regex_match, 3); params = g_new0(arg_int, 1); params->first = conn->ostr; params->second = (arg1 == NULL) ? 0 : atoi(arg1); event_signal(job_status_event, params); g_free(arg1); } /* command: "restart <job_id>" * * The interface has instructed the scheduler to restart a job that has been * paused. The argument for this command is required and is the jq_pk for * the job that should be restarted. */ else if(strcmp(cmd, "restart") == 0) { arg1 = g_match_info_fetch(regex_match, 3); if(arg1 == NULL) { arg1 = g_strdup(buffer); WARNING("received invalid restart command: %s", buffer); snprintf(buffer, sizeof(buffer) - 1, "ERROR: Invalid restart command: %s\n", arg1); g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL); g_free(arg1); } else { params = g_new0(arg_int, 1); params->second = atoi(arg1); params->first = g_tree_lookup(scheduler->job_list, ¶ms->second); event_signal(job_restart_event, params); g_free(arg1); } } /* command: "verbose <job_id|level> [level]" * * The interface has either requested a change in a verbose level, or it * has requested the current verbose level. This command can have no * arguments, 1 argument or 2 arguments. * * no arguments: respond with the verbose level of the scheduler * 1 argument: change the verbose level of the scheduler to the argument * 2 arguments: change the verbose level of the job with the jq_pk of the * first arguement to the second argument */ else if(strcmp(cmd, "verbose") == 0) { arg1 = g_match_info_fetch(regex_match, 3); arg2 = g_match_info_fetch(regex_match, 5); if(arg1 == NULL) { if(verbose < 8) { sprintf(buffer, "level: %d\n", verbose); } else { strcpy(buffer, "mask: h d i e s a j\nmask: "); for(i = 1; i < 0x10000; i <<= 1) strcat(buffer, i & verbose ? "1 " : "0 "); strcat(buffer, "\n"); } g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL); } else if(arg2 == NULL) { verbose = atoi(arg1); g_free(arg1); } else { i = atoi(arg1); if((job = g_tree_lookup(scheduler->job_list, &i)) == NULL) { g_free(cmd); cmd = g_strdup_printf("Invalid verbose command: \"%s\"\n", buffer); g_output_stream_write(conn->ostr, cmd, strlen(cmd), NULL, NULL); } else { job->verbose = atoi(arg2); event_signal(job_verbose_event, job); } g_free(arg1); g_free(arg2); } } /* command: "priority <job_id> <level>" * * Scheduler should change the priority of a job. This will change the * systems priority of the relevant job and change the priority of the job * in the database to match. Both arguments are required for this command. */ else if(strcmp(cmd, "priority") == 0) { arg1 = g_match_info_fetch(regex_match, 3); arg2 = g_match_info_fetch(regex_match, 5); if(arg1 != NULL && arg2 != NULL) { i = atoi(arg1); params = g_new0(arg_int, 1); params->first = g_tree_lookup(scheduler->job_list, &i); params->second = atoi(arg2); event_signal(job_priority_event, params); g_free(arg1); g_free(arg2); } else { if(arg1) g_free(arg1); if(arg2) g_free(arg2); arg1 = g_strdup(buffer); WARNING("Invalid priority command: %s\n", buffer); snprintf(buffer, sizeof(buffer) - 1, "ERROR: Invalid priority command: %s\n", arg1); g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL); g_free(arg1); } } /* command: "database" * * The scheduler should check the database. This will normaly be sent by * the ui when a new job has been queue and must be run. */ else if(strcmp(cmd, "database") == 0) { event_signal(database_update_event, NULL); } /* command: unknown * * The command sent does not match any of the known commands, log an error * and inform the interface that this wasn't a command. */ else { g_output_stream_write(conn->ostr, "Invalid command: \"", 18, NULL, NULL); g_output_stream_write(conn->ostr, buffer, strlen(buffer), NULL, NULL); g_output_stream_write(conn->ostr, "\"\n", 2, NULL, NULL); con_printf(main_log, "ERROR %s.%d: Interface received invalid command: %s\n", __FILE__, __LINE__, cmd); } g_match_info_free(regex_match); g_free(cmd); memset(buffer, '\0', sizeof(buffer)); } interface_conn_destroy(conn); return; }
static enum http_rc_e handler_action (struct http_request_s *rq, struct http_reply_ctx_s *rp) { gboolean _boolhdr (const gchar * n) { return metautils_cfg_get_bool ( (gchar *) g_tree_lookup (rq->tree_headers, n), FALSE); } // Get a request id for the current request const gchar *reqid = g_tree_lookup (rq->tree_headers, PROXYD_HEADER_REQID); if (reqid) oio_ext_set_reqid(reqid); else oio_ext_set_random_reqid(); // Then parse the request to find a handler struct oio_url_s *url = NULL; struct oio_requri_s ruri = {NULL, NULL, NULL, NULL}; oio_requri_parse (rq->req_uri, &ruri); struct path_matching_s **matchings = _metacd_match (rq->cmd, ruri.path); GRID_TRACE2("URI path[%s] query[%s] fragment[%s] matches[%u]", ruri.path, ruri.query, ruri.fragment, g_strv_length((gchar**)matchings)); GQuark gq_count = gq_count_unexpected; GQuark gq_time = gq_time_unexpected; enum http_rc_e rc; if (!*matchings) { rp->set_content_type ("application/json"); rp->set_body_gstr (g_string_new("{\"status\":404,\"message\":\"No handler found\"}")); rp->set_status (HTTP_CODE_NOT_FOUND, "No handler found"); rp->finalize (); rc = HTTPRC_DONE; } else { struct req_args_s args = {NULL,NULL,NULL, NULL,NULL, 0}; args.req_uri = &ruri; args.matchings = matchings; args.rq = rq; args.rp = rp; if (_boolhdr (PROXYD_HEADER_NOEMPTY)) args.flags |= FLAG_NOEMPTY; args.url = url = _metacd_load_url (&args); rp->subject(oio_url_get(url, OIOURL_HEXID)); gq_count = (*matchings)->last->gq_count; gq_time = (*matchings)->last->gq_time; GRID_TRACE("URL %s", oio_url_get(args.url, OIOURL_WHOLE)); req_handler_f handler = (*matchings)->last->u; rc = (*handler) (&args); } gint64 spent = oio_ext_monotonic_time () - rq->client->time.evt_in; network_server_stat_push4 (rq->client->server, TRUE, gq_count, 1, gq_count_all, 1, gq_time, spent, gq_time_all, spent); path_matching_cleanv (matchings); oio_requri_clear (&ruri); oio_url_pclean (&url); return rc; }
static void GCC_INLINE freecell_solver_cache_stacks( freecell_solver_hard_thread_t * hard_thread, fcs_state_with_locations_t * new_state ) { int a; #if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH) SFO_hash_value_t hash_value_int; #endif void * cached_stack; char * new_ptr; freecell_solver_instance_t * instance = hard_thread->instance; int stacks_num = instance->stacks_num; for(a=0 ; a<stacks_num ; a++) { /* * If the stack is not a copy - it is already cached so skip * to the next stack * */ if (! (new_state->stacks_copy_on_write_flags & (1 << a))) { continue; } /* new_state->s.stacks[a] = realloc(new_state->s.stacks[a], fcs_stack_len(new_state->s, a)+1); */ fcs_compact_alloc_typed_ptr_into_var(new_ptr, char, hard_thread->stacks_allocator, (fcs_stack_len(new_state->s, a)+1)); memcpy(new_ptr, new_state->s.stacks[a], (fcs_stack_len(new_state->s, a)+1)); new_state->s.stacks[a] = new_ptr; #if FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH /* Calculate the hash value for the stack */ /* This hash function was ripped from the Perl source code. * (It is not derived work however). */ { const char * s_ptr = (char*)(new_state->s.stacks[a]); const char * s_end = s_ptr+fcs_stack_len(new_state->s, a)+1; hash_value_int = 0; while (s_ptr < s_end) { hash_value_int += (hash_value_int << 5) + *(s_ptr++); } hash_value_int += (hash_value_int >> 5); } if (hash_value_int < 0) { /* * This is a bit mask that nullifies the sign bit of the * number so it will always be positive * */ hash_value_int &= (~(1<<((sizeof(hash_value_int)<<3)-1))); } cached_stack = (void *)freecell_solver_hash_insert( instance->stacks_hash, new_state->s.stacks[a], freecell_solver_lookup2_hash_function( (ub1 *)new_state->s.stacks[a], (fcs_stack_len(new_state->s, a)+1), 24 ), hash_value_int, 1 ); #define replace_with_cached(condition_expr) \ if (cached_stack != NULL) \ { \ fcs_compact_alloc_release(hard_thread->stacks_allocator); \ new_state->s.stacks[a] = cached_stack; \ } replace_with_cached(cached_stack != NULL); #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_AVL_TREE) || (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_REDBLACK_TREE) cached_stack = #if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_AVL_TREE) avl_insert( #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL_REDBLACK_TREE) rb_insert( #endif instance->stacks_tree, new_state->s.stacks[a] ); #if 0 ) /* In order to settle gvim and other editors that are keen on parenthesis matching */ #endif replace_with_cached(cached_stack != NULL); #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBREDBLACK_TREE) cached_stack = (void *)rbsearch( new_state->s.stacks[a], instance->stacks_tree ); replace_with_cached(cached_stack != new_state->s.stacks[a]); #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_TREE) cached_stack = g_tree_lookup( instance->stacks_tree, (gpointer)new_state->s.stacks[a] ); /* replace_with_cached contains an if statement */ replace_with_cached(cached_stack != NULL) else { g_tree_insert( instance->stacks_tree, (gpointer)new_state->s.stacks[a], (gpointer)new_state->s.stacks[a] ); } #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH) cached_stack = g_hash_table_lookup( instance->stacks_hash, (gconstpointer)new_state->s.stacks[a] ); replace_with_cached(cached_stack != NULL) else { g_hash_table_insert( instance->stacks_hash, (gpointer)new_state->s.stacks[a], (gpointer)new_state->s.stacks[a] ); } #endif }
int req_parser_add_text(req_parser *r, const char *data, size_t len) { const char *end; if (!g_utf8_validate(data, len, &end)) { return REQ_PARSER_PARSE_INVALID_REQUEST; } int result = REQ_PARSER_PARSE_PARTIAL_REQUEST; int mode = (r->method == REQ_PARSER_METHOD_INVALID) ? MODE_REQUEST_LINE : MODE_HEADER_LINE; const gchar *headerQuark = NULL; char buf[HEADER_BUF_SIZE]; const char *token_start = data; const char *i; for (i = data; (i < end) && *i; i = g_utf8_next_char(i)) { result = REQ_PARSER_PARSE_PARTIAL_REQUEST; gunichar c = g_utf8_get_char(i); if (c == '\r') { i = g_utf8_next_char(i); c = g_utf8_get_char(i); } if ((c == '\n') && (*g_utf8_prev_char(i) != '\r')) { fprintf(stderr, "ERROR - Encountered a newline without a preceding carriage return.\n"); req_parser_reset(r); return REQ_PARSER_PARSE_INVALID_REQUEST; } switch (mode) { case MODE_REQUEST_LINE: if (c == ' ') { if (r->method == REQ_PARSER_METHOD_INVALID) { if (strncmp("GET", token_start, 3) == 0) r->method = REQ_PARSER_METHOD_GET; else if (strncmp("HEAD", token_start, 4) == 0) r->method = REQ_PARSER_METHOD_HEAD; else if (strncmp("POST", token_start, 4) == 0) r->method = REQ_PARSER_METHOD_POST; else if (strncmp("OPTIONS", token_start, 7) == 0) r->method = REQ_PARSER_METHOD_OPTIONS; else { fprintf(stderr, "ERROR - Unknown method\n"); req_parser_reset(r); return REQ_PARSER_PARSE_INVALID_REQUEST; } // skip over the separating space i = g_utf8_next_char(i); token_start = i; } else if (r->path == NULL) { parse_uri(r, token_start, (i - token_start)); // skip over the separating space i = g_utf8_next_char(i); token_start = i; } else { fprintf(stderr, "ERROR - Too many spaces in request line\n"); req_parser_reset(r); return REQ_PARSER_PARSE_INVALID_REQUEST; } } else if (c == '\n') { if (strncmp("HTTP/1.1", token_start, min(8, i - token_start)) != 0) { fprintf(stderr, "ERROR - Unsupported HTTP version\n"); req_parser_reset(r); return REQ_PARSER_PARSE_INVALID_REQUEST; } token_start = NULL; mode = MODE_HEADER_LINE; } break; case MODE_HEADER_LINE: if (token_start == NULL) { token_start = i; } if ((token_start == i) && (c == '\n')) { result = REQ_PARSER_PARSE_OK; mode = MODE_REQUEST_BODY; } else if ((headerQuark == NULL) && (c == ':')) { memset(buf, 0, HEADER_BUF_SIZE); memcpy(buf, token_start, min((i - token_start), HEADER_BUF_SIZE - 1)); headerQuark = g_intern_string(buf); token_start = NULL; // skip over the separating space i = g_utf8_next_char(i); } else if (c == '\n') { if (!r->headers) { r->headers = g_tree_new_full(quarkcmp, NULL, NULL, gstring_destroy_notify); } // Subtract one since we don't want the "\r" in the header g_tree_insert(r->headers, (gpointer)headerQuark, g_string_new_len(token_start, (i - token_start) - 1)); token_start = NULL; headerQuark = NULL; } break; case MODE_REQUEST_BODY: if (r->body == NULL) { token_start = i; if (!r->headers) { r->headers = g_tree_new_full(quarkcmp, NULL, NULL, gstring_destroy_notify); } GString *length_header = g_tree_lookup(r->headers, g_intern_static_string("Content-Length")); if (length_header) { int length = atoi(length_header->str); size_t bytes_remaining = len - (data - i); if (bytes_remaining < (size_t)length) { fprintf(stderr, "ERROR - Body incomplete.\n"); req_parser_reset(r); return REQ_PARSER_PARSE_INVALID_REQUEST; } r->body = g_string_new_len(i, length); i = i + length; } else { size_t length = len - (data - i); r->body = g_string_new_len(i, length); i = i + length; } result = REQ_PARSER_PARSE_OK; } else if (c == '\n') { result = REQ_PARSER_PARSE_OK; } break; } } r->status = result; return result; }
static void GCC_INLINE fc_solve_cache_stacks( fc_solve_hard_thread_t * hard_thread, fcs_state_t * new_state_key, fcs_state_extra_info_t * new_state_val ) { int a; #if (FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH) #ifdef FCS_ENABLE_SECONDARY_HASH_VALUE SFO_hash_value_t hash_value_int; #endif #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_JUDY) PWord_t * PValue; #endif void * cached_stack; char * new_ptr; fc_solve_instance_t * instance = hard_thread->instance; #ifndef HARD_CODED_NUM_STACKS DECLARE_AND_SET_GAME_PARAMS(); #endif fcs_cards_column_t column; register int col_len; fcs_compact_allocator_t * stacks_allocator; stacks_allocator = &(hard_thread->allocator); for(a=0 ; a < LOCAL_STACKS_NUM ; a++) { /* * If the stack is not a copy - it is already cached so skip * to the next stack * */ if (! (new_state_val->stacks_copy_on_write_flags & (1 << a))) { continue; } column = fcs_state_get_col(*new_state_key, a); col_len = (fcs_col_len(column)+1); new_ptr = (char*)fcs_compact_alloc_ptr(stacks_allocator, col_len); memcpy(new_ptr, column, col_len); new_state_key->stacks[a] = new_ptr; #if FCS_STACK_STORAGE == FCS_STACK_STORAGE_INTERNAL_HASH #ifdef FCS_ENABLE_SECONDARY_HASH_VALUE /* Calculate the hash value for the stack */ /* This hash function was ripped from the Perl source code. * (It is not derived work however). */ { const char * s_ptr = (char*)(new_state_key->stacks[a]); const char * s_end = s_ptr+fcs_col_len(s_ptr)+1; hash_value_int = 0; while (s_ptr < s_end) { hash_value_int += (hash_value_int << 5) + *(s_ptr++); } hash_value_int += (hash_value_int >> 5); } if (hash_value_int < 0) { /* * This is a bit mask that nullifies the sign bit of the * number so it will always be positive * */ hash_value_int &= (~(1<<((sizeof(hash_value_int)<<3)-1))); } #endif { void * dummy; int verdict; column = fcs_state_get_col(*new_state_key, a); verdict = fc_solve_hash_insert( &(instance->stacks_hash), column, column, &cached_stack, &dummy, perl_hash_function( (ub1 *)new_state_key->stacks[a], col_len ) #ifdef FCS_ENABLE_SECONDARY_HASH_VALUE , hash_value_int #endif ); replace_with_cached(verdict); } #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GOOGLE_DENSE_HASH) { int verdict; void * dummy; column = fcs_state_get_col(*new_state_key, a); verdict = fc_solve_columns_google_hash_insert( instance->stacks_hash, column, column, &cached_stack, &dummy ); replace_with_cached(verdict); } #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBAVL2_TREE) cached_stack = fcs_libavl2_stacks_tree_insert( instance->stacks_tree, new_state_key->stacks[a] ); replace_with_cached(cached_stack != NULL); #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_LIBREDBLACK_TREE) cached_stack = (void *)rbsearch( new_state_key->stacks[a], instance->stacks_tree ); replace_with_cached(cached_stack != new_state_key->stacks[a]); #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_TREE) cached_stack = g_tree_lookup( instance->stacks_tree, (gpointer)new_state_key->stacks[a] ); /* replace_with_cached contains an if statement */ replace_with_cached(cached_stack != NULL) else { g_tree_insert( instance->stacks_tree, (gpointer)new_state_key->stacks[a], (gpointer)new_state_key->stacks[a] ); } #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_GLIB_HASH) cached_stack = g_hash_table_lookup( instance->stacks_hash, (gconstpointer)new_state_key->stacks[a] ); replace_with_cached(cached_stack != NULL) else { g_hash_table_insert( instance->stacks_hash, (gpointer)new_state_key->stacks[a], (gpointer)new_state_key->stacks[a] ); } #elif (FCS_STACK_STORAGE == FCS_STACK_STORAGE_JUDY) column = fcs_state_get_col(*new_state_key, a); JHSI( PValue, instance->stacks_judy_array, column, (1+fcs_col_len(column)) ); /* later_todo : Handle out-of-memory. */ if (*PValue == 0) { /* A new stack */ *PValue = (PWord_t)column; } else { cached_stack = (void *)(*PValue); replace_with_cached(1); } #else #error FCS_STACK_STORAGE is not set to a good value. #endif } }
GCC_INLINE int fc_solve_check_and_add_state( fc_solve_soft_thread_t * soft_thread, fcs_state_extra_info_t * new_state_val, fcs_state_extra_info_t * * existing_state_val ) { #if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH) #ifdef FCS_ENABLE_SECONDARY_HASH_VALUE SFO_hash_value_t hash_value_int; #endif #endif #if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT) fcs_standalone_state_ptrs_t * pos_ptr; int found; #endif fc_solve_hard_thread_t * hard_thread = soft_thread->hard_thread; fc_solve_instance_t * instance = hard_thread->instance; fcs_state_t * new_state_key = new_state_val->key; int is_state_new; if (check_if_limits_exceeded()) { return FCS_STATE_BEGIN_SUSPEND_PROCESS; } if ((instance->max_depth >= 0) && (new_state_val->depth >= instance->max_depth)) { return FCS_STATE_EXCEEDS_MAX_DEPTH; } fc_solve_cache_stacks(hard_thread, new_state_key, new_state_val); fc_solve_canonize_state(new_state_val, INSTANCE_FREECELLS_NUM, INSTANCE_STACKS_NUM ); /* The objective of this part of the code is: 1. To check if new_state_key / new_state_val is already in the prev_states collection. 2. If not, to add it and to set check to true. 3. If so, to set check to false. */ #if (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INTERNAL_HASH) #ifdef FCS_ENABLE_SECONDARY_HASH_VALUE { const char * s_ptr = (char*)new_state_key; const char * s_end = s_ptr+sizeof(*new_state_key); hash_value_int = 0; while (s_ptr < s_end) { hash_value_int += (hash_value_int << 5) + *(s_ptr++); } hash_value_int += (hash_value_int>>5); } if (hash_value_int < 0) { /* * This is a bit mask that nullifies the sign bit of the * number so it will always be positive * */ hash_value_int &= (~(1<<((sizeof(hash_value_int)<<3)-1))); } #endif { void * existing_key_void, * existing_val_void; is_state_new = (fc_solve_hash_insert( &(instance->hash), new_state_key, new_state_val, &existing_key_void, &existing_val_void, perl_hash_function( (ub1 *)new_state_key, sizeof(*new_state_key) ) #ifdef FCS_ENABLE_SECONDARY_HASH_VALUE , hash_value_int #endif ) == 0); if (! is_state_new) { *existing_state_val = existing_val_void; } } #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GOOGLE_DENSE_HASH) { void * existing_key_void, * existing_val_void; is_state_new = (fc_solve_states_google_hash_insert( instance->hash, new_state_key, new_state_val, &existing_key_void, &existing_val_void ) == 0); if (! is_state_new) { *existing_state_val = existing_val_void; } } #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_INDIRECT) /* Try to see if the state is found in indirect_prev_states */ if ((pos_ptr = (fcs_standalone_state_ptrs_t *)bsearch(&new_state_key, instance->indirect_prev_states, instance->num_indirect_prev_states, sizeof(instance->indirect_prev_states[0]), fc_solve_state_compare_indirect)) == NULL) { /* It isn't in prev_states, but maybe it's in the sort margin */ pos_ptr = (fcs_standalone_state_ptrs_t *)fc_solve_bsearch( &new_state_key, instance->indirect_prev_states_margin, instance->num_prev_states_margin, sizeof(instance->indirect_prev_states_margin[0]), fc_solve_state_compare_indirect_with_context, NULL, &found); if (found) { is_state_new = 0; *existing_state_val = pos_ptr->val; } else { /* Insert the state into its corresponding place in the sort * margin */ memmove((void*)(pos_ptr+1), (void*)pos_ptr, sizeof(*pos_ptr) * (instance->num_prev_states_margin- (pos_ptr-instance->indirect_prev_states_margin) )); pos_ptr->key = new_state_key; pos_ptr->val = new_state_val; instance->num_prev_states_margin++; if (instance->num_prev_states_margin >= PREV_STATES_SORT_MARGIN) { /* The sort margin is full, let's combine it with the main array */ instance->indirect_prev_states = realloc( instance->indirect_prev_states, sizeof(instance->indirect_prev_states[0]) * (instance->num_indirect_prev_states + instance->num_prev_states_margin ) ); fc_solve_merge_large_and_small_sorted_arrays( instance->indirect_prev_states, instance->num_indirect_prev_states, instance->indirect_prev_states_margin, instance->num_prev_states_margin, sizeof(instance->indirect_prev_states[0]), fc_solve_state_compare_indirect_with_context, NULL ); instance->num_indirect_prev_states += instance->num_prev_states_margin; instance->num_prev_states_margin=0; } is_state_new = 1; } } else { *existing_state_val = pos_ptr->val; is_state_new = 0; } #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBREDBLACK_TREE) *existing_state_val = (fcs_state_extra_info_t *)rbsearch(new_state_val, instance->tree ); is_state_new = ((*existing_state_val) == new_state_val); #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_LIBAVL2_TREE) *existing_state_val = (fcs_state_extra_info_t *) fcs_libavl2_states_tree_insert(instance->tree, new_state_val); is_state_new = ((*existing_state_val) == NULL); #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_TREE) *existing_state_val = g_tree_lookup(instance->tree, (gpointer)new_state_key); if (*existing_state_val == NULL) { /* The new state was not found. Let's insert it. * The value must be the same as the key, so g_tree_lookup() * will return it. */ g_tree_insert( instance->tree, (gpointer)new_state_key, (gpointer)new_state_val ); is_state_new = 1; } else { is_state_new = 0; } #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_GLIB_HASH) *existing_state_val = g_hash_table_lookup(instance->hash, (gpointer)new_state_key); if (*existing_state_val == NULL) { /* The new state was not found. Let's insert it. * The value must be the same as the key, so g_tree_lookup() * will return it. */ g_hash_table_insert( instance->hash, (gpointer)new_state_key, (gpointer)new_state_val ); is_state_new = 1; } else { is_state_new = 0; } #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_DB_FILE) { DBT key, value; key.data = new_state; key.size = sizeof(*new_state); if (instance->db->get( instance->db, NULL, &key, &value, 0 ) == 0) { /* The new state was not found. Let's insert it. * The value must be the same as the key, so g_tree_lookup() * will return it. */ value.data = key.data; value.size = key.size; instance->db->put( instance->db, NULL, &key, &value, 0); is_state_new = 1; } else { is_state_new = 0; } } #elif (FCS_STATE_STORAGE == FCS_STATE_STORAGE_JUDY) { PWord_t * PValue; JHSI(PValue, instance->judy_array, new_state_key, sizeof(*new_state_key)); /* later_todo : Handle out-of-memory. */ if (*PValue == 0) { /* A new state. */ is_state_new = 1; *PValue = (PWord_t)(*existing_state_val = new_state_val); } else { /* Already exists. */ is_state_new = 0; *existing_state_val = (fcs_state_extra_info_t *)(*PValue); } } #else #error no define #endif if (is_state_new) { /* The new state was not found in the cache, and it was already inserted */ if (new_state_val->parent_val) { new_state_val->parent_val->num_active_children++; } instance->num_states_in_collection++; if (new_state_val->moves_to_parent != NULL) { new_state_val->moves_to_parent = fc_solve_move_stack_compact_allocate( hard_thread, new_state_val->moves_to_parent ); } return FCS_STATE_DOES_NOT_EXIST; } else { return FCS_STATE_ALREADY_EXISTS; } }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_desc_t *cmd = NULL; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; xmmsv_t *error, *arguments; uint32_t objid, cmdid; gint i; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (!xmms_ipc_msg_get_value (msg, &arguments)) { xmms_log_error ("Cannot read command arguments. " "Ignoring command."); return; } if (objid == XMMS_IPC_OBJECT_SIGNAL) { if (cmdid == XMMS_IPC_CMD_SIGNAL) { xmms_ipc_register_signal (client, msg, arguments); } else if (cmdid == XMMS_IPC_CMD_BROADCAST) { xmms_ipc_register_broadcast (client, msg, arguments); } else { xmms_log_error ("Bad command id (%d) for signal object", cmdid); } goto out; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); goto out; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); goto out; } if (object->cmds) cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid)); if (!cmd) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); goto out; } xmms_object_cmd_arg_init (&arg); for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (!type_and_msg_to_arg (cmd->args[i], arguments, &arg, i)) { xmms_log_error ("Error parsing args"); if (objid == XMMS_IPC_OBJECT_MAIN && cmdid == XMMS_IPC_CMD_HELLO) { xmms_log_error ("Couldn't parse hello message. " "Maybe the client or libxmmsclient " "needs to be updated."); } retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error ("Corrupt msg"); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); goto err; } } xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could omit setting the command to _CMD_ERROR * and let the client check whether the value it got is an * error xmmsv_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); error = xmmsv_new_error (xmms_error_message_get (&arg.error)); xmms_ipc_msg_put_value (retmsg, error); xmmsv_unref (error); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (arg.values[i]) xmmsv_unref (arg.values[i]); } xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); out: if (arguments) { xmmsv_unref (arguments); } }
static void process_msg (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { xmms_object_t *object; xmms_object_cmd_desc_t *cmd = NULL; xmms_object_cmd_arg_t arg; xmms_ipc_msg_t *retmsg; uint32_t objid, cmdid; gint i; g_return_if_fail (msg); objid = xmms_ipc_msg_get_object (msg); cmdid = xmms_ipc_msg_get_cmd (msg); if (objid == XMMS_IPC_OBJECT_SIGNAL && cmdid == XMMS_IPC_CMD_SIGNAL) { gint32 signalid; if (!xmms_ipc_msg_get_int32 (msg, &signalid)) { xmms_log_error ("No signalid in this msg?!"); return; } if (signalid < 0 || signalid >= XMMS_IPC_SIGNAL_END) { xmms_log_error ("Bad signal id (%d)", signalid); return; } g_mutex_lock (client->lock); client->pendingsignals[signalid] = xmms_ipc_msg_get_cookie (msg); g_mutex_unlock (client->lock); return; } else if (objid == XMMS_IPC_OBJECT_SIGNAL && cmdid == XMMS_IPC_CMD_BROADCAST) { gint32 broadcastid; if (!xmms_ipc_msg_get_int32 (msg, &broadcastid)) { xmms_log_error ("No broadcastid in this msg?!"); return; } if (broadcastid < 0 || broadcastid >= XMMS_IPC_SIGNAL_END) { xmms_log_error ("Bad broadcast id (%d)", broadcastid); return; } g_mutex_lock (client->lock); client->broadcasts[broadcastid] = g_list_append (client->broadcasts[broadcastid], GUINT_TO_POINTER (xmms_ipc_msg_get_cookie (msg))); g_mutex_unlock (client->lock); return; } if (objid >= XMMS_IPC_OBJECT_END) { xmms_log_error ("Bad object id (%d)", objid); return; } g_mutex_lock (ipc_object_pool_lock); object = ipc_object_pool->objects[objid]; g_mutex_unlock (ipc_object_pool_lock); if (!object) { xmms_log_error ("Object %d was not found!", objid); return; } if (cmdid >= XMMS_IPC_CMD_END) { xmms_log_error ("Bad command id (%d)", cmdid); return; } if (object->cmds) cmd = g_tree_lookup (object->cmds, GUINT_TO_POINTER (cmdid)); if (!cmd) { xmms_log_error ("No such cmd %d on object %d", cmdid, objid); return; } xmms_object_cmd_arg_init (&arg); for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { if (!type_and_msg_to_arg (cmd->args[i], msg, &arg, i)) { xmms_log_error ("Error parsing args"); retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); xmms_ipc_msg_put_string (retmsg, "Corrupt msg"); goto err; } } xmms_object_cmd_call (object, cmdid, &arg); if (xmms_error_isok (&arg.error)) { retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); } else { /* FIXME: or we could change the client code to transform * CMD_ERROR to an error value_t. If so, don't forget to * update the client-side of IPC too. */ retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_ERROR); xmms_ipc_msg_put_string (retmsg, xmms_error_message_get (&arg.error)); /* retmsg = xmms_ipc_msg_new (objid, XMMS_IPC_CMD_REPLY); xmms_ipc_handle_cmd_value (retmsg, arg.retval); */ } if (arg.retval) xmmsv_unref (arg.retval); err: for (i = 0; i < XMMS_OBJECT_CMD_MAX_ARGS; i++) { xmmsv_unref (arg.values[i]); } xmms_ipc_msg_set_cookie (retmsg, xmms_ipc_msg_get_cookie (msg)); g_mutex_lock (client->lock); xmms_ipc_client_msg_write (client, retmsg); g_mutex_unlock (client->lock); }
gpointer tgenpool_getRandom(TGenPool* pool) { TGEN_ASSERT(pool); const gint position = (gint) (rand() % g_tree_nnodes(pool->items)); return (gpointer)g_tree_lookup(pool->items, &position); }