/* \brief This dispatches out packets to awaiting subscribers (if any) If the payload or sequnce number matches what's in the packet, this packet is copied and pushed down the supplied queue to the lucky winner. This allows multiple subscribers per payloadID or sequence number, which offers some interesting flexibility \param packet is a pointer to the new packet \see FreeEMS_Packet */ G_MODULE_EXPORT void dispatch_packet_queues(FreeEMS_Packet *packet) { static GHashTable *payloads = NULL; static GHashTable *sequences = NULL; static GMutex *mutex = NULL; GAsyncQueue *queue = NULL; guint8 header = packet->data[0]; guint i = 0; GList *list = NULL; if (!mutex) mutex = (GMutex *)DATA_GET(global_data,"queue_mutex"); if (!payloads) payloads = (GHashTable *)DATA_GET(global_data,"payload_id_queue_hash"); if (!sequences) sequences = (GHashTable *)DATA_GET(global_data,"sequence_num_queue_hash"); g_return_if_fail(mutex); g_mutex_lock(mutex); /* If sequence set, look for it and dispatch if found */ if ((sequences) && ((packet->header_bits & HAS_SEQUENCE_MASK) > 0)) { list = (GList *)g_hash_table_lookup(sequences,GINT_TO_POINTER((GINT)packet->seq_num)); if (list) { for (i=0;i<g_list_length(list);i++) { queue = (GAsyncQueue *)g_list_nth_data(list,i); if (queue) { g_async_queue_ref(queue); g_async_queue_push(queue,(gpointer)packet_deep_copy(packet)); g_async_queue_unref(queue); } } } } if (payloads) { /* If payload ID matches, dispatch if found */ list = (GList *)g_hash_table_lookup(payloads,GINT_TO_POINTER((GINT)packet->payload_id)); if (list) { for (i=0;i<g_list_length(list);i++) { queue = (GAsyncQueue *)g_list_nth_data(list,i); if (queue) { g_async_queue_ref(queue); g_async_queue_push(queue,(gpointer)packet_deep_copy(packet)); g_async_queue_unref(queue); } } } } g_mutex_unlock(mutex); freeems_packet_cleanup(packet); }
/* Our polling thread */ gpointer apollo_orbiter(gpointer gp_queue) { FinishedNotify * pn = gp_queue; g_async_queue_ref(pn->queue); while(TRUE) { g_print("\n-----------\n\n"); gpointer thread_data = g_async_queue_pop(pn->queue); if(thread_data == THREAD_TERMINATOR) { g_printerr("\n-- Terminating --\n"); break; } else { GlyrQuery * q = thread_data; GlyrMemCache * head = glyr_get(q,NULL,NULL); if(head != NULL) { g_print("//////// ITEM %d ////////\n",++pn->counter); glyr_cache_print(head); glyr_free_list(head); g_print("/////////////////////////\n"); } glyr_query_destroy(q); } } g_async_queue_unref(pn->queue); return NULL; }
static void *process_pending_work(void *unused) { struct pending_work *item; g_async_queue_ref(pending_work_queue); while (1) { item=g_async_queue_pop(pending_work_queue); switch (item->proc) { case nr_proto_client_check_int: if (item->integer == INT_VALUE) proto_client_check_int_send_async_reply( item->msg); else proto_client_check_int_send_async_reply_error( item->msg, 1); break; case nr_proto_notify: pthread_mutex_lock(item->lock); pthread_cond_broadcast(item->cond); pthread_mutex_unlock(item->lock); break; } g_slice_free(struct pending_work, item); } return NULL; }
bool Action::run_one( GAsyncQueue * queue , gulong wait_ms ) { g_assert( queue ); g_async_queue_ref( queue ); Action * action = 0; if ( wait_ms == 0 ) { action = ( Action * ) g_async_queue_try_pop( queue ); } else { action = ( Action * ) Util::g_async_queue_timeout_pop( queue , wait_ms * 1000 ); } g_async_queue_unref( queue ); if ( action ) { run_internal( action ); delete action; return true; } return false; }
/** * message_queue_source_new: * @queue: the queue to check * @destroy_message: (nullable): function to free a message, or %NULL * @cancellable: (nullable): a #GCancellable, or %NULL * * Create a new #MessageQueueSource, a type of #GSource which dispatches for * each message queued to it. * * If a callback function of type #MessageQueueSourceFunc is connected to the * returned #GSource using g_source_set_callback(), it will be invoked for each * message, with the message passed as its first argument. It is responsible for * freeing the message. If no callback is set, messages are automatically freed * as they are queued. * * Returns: (transfer full): a new #MessageQueueSource */ GSource * message_queue_source_new (GAsyncQueue *queue, GDestroyNotify destroy_message, GCancellable *cancellable) { GSource *source; /* alias of @message_queue_source */ MessageQueueSource *message_queue_source; /* alias of @source */ g_return_val_if_fail (queue != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); source = g_source_new (&message_queue_source_funcs, sizeof (MessageQueueSource)); message_queue_source = (MessageQueueSource *) source; /* The caller can overwrite this name with something more useful later. */ g_source_set_name (source, "MessageQueueSource"); message_queue_source->queue = g_async_queue_ref (queue); message_queue_source->destroy_message = destroy_message; /* Add a cancellable source. */ if (cancellable != NULL) { GSource *cancellable_source; cancellable_source = g_cancellable_source_new (cancellable); g_source_set_dummy_callback (cancellable_source); g_source_add_child_source (source, cancellable_source); g_source_unref (cancellable_source); } return source; }
void proc_emu_on_io_in(struct connection *con, struct processor_data *pd) { g_debug("%s con %p pd %p", __PRETTY_FUNCTION__, con, pd); struct emu_ctx *ctx = pd->ctx; int offset = MAX(ctx->offset-300, 0); void *streamdata = NULL; int32_t size = bistream_get_stream(pd->bistream, bistream_in, offset, -1, &streamdata); int ret = 0; if( size != -1 ) { struct emu *e = emu_new(); #if 0 emu_cpu_debugflag_set(emu_cpu_get(e), instruction_string); emu_log_level_set(emu_logging_get(e),EMU_LOG_DEBUG); #endif ret = emu_shellcode_test(e, streamdata, size); emu_free(e); ctx->offset += size; if( ret >= 0 ) { struct incident *ix = incident_new("dionaea.shellcode.detected"); GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds); g_async_queue_push(aq, async_cmd_new(async_incident_report, ix)); g_async_queue_unref(aq); ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger); g_debug("shellcode found offset %i", ret); profile(ctx->config, con, streamdata, size, ret); pd->state = processor_done; } g_free(streamdata); } }
/*! \brief io_cmd() is called from all over the gui to kick off a threaded I/O command. A command enumeration and an option block of data is passed and this function allocates an Io_Message and shoves it down an GAsyncQueue to the main thread dispatcher which runs things and then passes any needed information back to the gui via another GAsyncQueue which takes care of any post thread GUI updates. (which can NOT be done in a thread context due to reentrancy and deadlock conditions) \param cmd_name is the name of the command to look for in the commands_hash \param data is the additional data for fringe cases.. */ G_MODULE_EXPORT void io_cmd(const gchar *cmd_name, void *data) { static GAsyncQueue *io_data_queue = NULL; static void (*build_output_message_f)(Io_Message *, Command *, gpointer); static GHashTable *commands_hash = NULL; Io_Message *message = NULL; Command *command = NULL; ENTER(); if (!commands_hash) commands_hash = (GHashTable *)DATA_GET(global_data,"commands_hash"); if (!io_data_queue) io_data_queue = (GAsyncQueue *)DATA_GET(global_data,"io_data_queue"); if (!build_output_message_f) get_symbol("build_output_message",(void **)&build_output_message_f); g_return_if_fail(build_output_message_f); g_return_if_fail(commands_hash); g_return_if_fail(io_data_queue); /* Fringe case for FUNC_CALL helpers that need to trigger * post_functions AFTER all their subhandlers have ran. We * call io_cmd with no cmd name and pack in the post functions into * the void pointer part. */ if (!cmd_name) { message = initialize_io_message(); message->command = g_new0(Command, 1); message->command->defer_post_functions = FALSE; message->command->post_functions = (GArray *)data; message->command->type = NULL_CMD; message->command->dynamic = TRUE; } /* Std io_message passed by string name */ else { command = (Command *)g_hash_table_lookup(commands_hash,cmd_name); if (!command) { MTXDBG(CRITICAL|IO_MSG|THREADS,_("Command %s is INVALID, aborting call\n"),cmd_name); EXIT(); return;; } message = initialize_io_message(); message->command = command; message->command->dynamic = FALSE; if (data) message->payload = data; if (command->type == WRITE_CMD) build_output_message_f(message,command,data); } g_async_queue_ref(io_data_queue); g_async_queue_push(io_data_queue,(gpointer)message); g_async_queue_unref(io_data_queue); EXIT(); return; }
// The query is assumed to be a static string that is not freed or modified. static void *db_queue_item_create(int flags, const char *q, ...) { GByteArray *a = g_byte_array_new(); darray_init(a); darray_add_int32(a, flags); darray_add_ptr(a, q); int t; char *p; va_list va; va_start(va, q); while((t = va_arg(va, int)) != DBQ_END && t != DBQ_RES) { switch(t) { case DBQ_NULL: darray_add_int32(a, DBQ_NULL); break; case DBQ_INT: darray_add_int32(a, DBQ_INT); darray_add_int32(a, va_arg(va, int)); break; case DBQ_INT64: darray_add_int32(a, DBQ_INT64); darray_add_int64(a, va_arg(va, gint64)); break; case DBQ_TEXT: p = va_arg(va, char *); if(p) { darray_add_int32(a, DBQ_TEXT); darray_add_string(a, p); } else darray_add_int32(a, DBQ_NULL); break; case DBQ_BLOB: t = va_arg(va, int); p = va_arg(va, char *); if(p) { darray_add_int32(a, DBQ_BLOB); darray_add_dat(a, p, t); } else darray_add_int32(a, DBQ_NULL); break; default: g_return_val_if_reached(NULL); } } if(t == DBQ_RES) { darray_add_int32(a, DBQ_RES); GAsyncQueue *queue = va_arg(va, GAsyncQueue *); g_async_queue_ref(queue); darray_add_ptr(a, queue); while((t = va_arg(va, int)) != DBQ_END) darray_add_int32(a, t); }
/*! *\brief Registers a queue for a subscriber such that whe na packet comes in matching the criteria a copy of the packet is pushed down that queue to the waiting subscriber \param type is an enumeration statign whether we are matching on payload ID OR sequence number (can't match on a combination of both yet) \param queue is a pointer to the queue where this packet should be sent on a match \param data is the payloadID or sequence number to match on */ G_MODULE_EXPORT void register_packet_queue(gint type, GAsyncQueue *queue, gint data) { static GHashTable *payloads = NULL; static GHashTable *sequences = NULL; static GMutex *mutex = NULL; GList *list = NULL; if (!mutex) mutex = (GMutex *)DATA_GET(global_data,"queue_mutex"); if (!payloads) payloads = (GHashTable *)DATA_GET(global_data,"payload_id_queue_hash"); if (!sequences) sequences = (GHashTable *)DATA_GET(global_data,"sequence_num_queue_hash"); g_return_if_fail(mutex); g_return_if_fail(queue); g_mutex_lock(mutex); switch ((FreeEMSArgTypes)type) { case PAYLOAD_ID: list = (GList *)g_hash_table_lookup(payloads,GINT_TO_POINTER(data)); g_async_queue_ref(queue); list = g_list_append(list,queue); /*printf("Paylod ID %i list added entry, list length %i\n",data,g_list_length(list));*/ g_hash_table_replace(payloads,GINT_TO_POINTER(data),list); break; case SEQUENCE_NUM: list = (GList *)g_hash_table_lookup(sequences,GINT_TO_POINTER(data)); g_async_queue_ref(queue); list = g_list_append(list,queue); /*printf("Sequence num %i list added entry, list length %i\n",data,g_list_length(list));*/ g_hash_table_replace(sequences,GINT_TO_POINTER(data),list); break; default: printf("Need to specific approrpriate criteria to match a packet\n"); break; } g_mutex_unlock(mutex); return; }
void Ekiga::Runtime::init () { // here we get a ref to the queue, which we'll release in quit queue = g_async_queue_new_full ((GDestroyNotify)free_message); struct source* source = (struct source *)g_source_new (&source_funcs, sizeof (struct source)); source->queue = queue; g_async_queue_ref (queue); // give a ref to the source g_source_attach ((GSource *)source, g_main_context_default ()); loop = g_main_loop_new (NULL, FALSE); }
void profile(struct emu_config *conf, struct connection *con, void *data, unsigned int size, unsigned int offset) { struct emu *e = emu_new(); struct emu_env *env = emu_env_new(e); env->profile = emu_profile_new(); // struct emu_cpu *cpu = emu_cpu_get(e); struct emu_memory *mem = emu_memory_get(e); emu_cpu_reg32_set(emu_cpu_get(e), esp, 0x0012fe98); emu_memory_write_block(mem, CODE_OFFSET, data, size); emu_cpu_eip_set(emu_cpu_get(e), CODE_OFFSET + offset); run(e, env); bool needemu = false; struct emu_profile_function *function; for( function = emu_profile_functions_first(env->profile->functions); !emu_profile_functions_istail(function); function = emu_profile_functions_next(function) ) { if( strcmp("recv", function->fnname) == 0 ) { g_message("Can not profile %s, emulating instead", function->fnname); needemu = true; } } if( needemu == true ) { emulate(conf, con, data, size, offset); } else { GString *str = g_string_new(NULL); json_profile_debug(env->profile, str); //printf("%s", str->str); struct incident *i = incident_new("dionaea.module.emu.profile"); incident_value_string_set(i, "profile", str); incident_value_con_set(i, "con", con); connection_ref(con); GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds); g_async_queue_push(aq, async_cmd_new(async_incident_report, i)); g_async_queue_unref(aq); ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger); } emu_env_free(env); emu_free(e); }
/** * oh_dequeue_session_event * @sid: * @event: * * * * Returns: **/ SaErrorT oh_dequeue_session_event(SaHpiSessionIdT sid, SaHpiTimeoutT timeout, struct oh_event *event) { struct oh_session *session = NULL; struct oh_event *devent = NULL; GTimeVal gfinaltime; GAsyncQueue *eventq = NULL; if (sid < 1 || (event == NULL)) return SA_ERR_HPI_INVALID_PARAMS; g_static_rec_mutex_lock(&oh_sessions.lock); /* Locked session table */ session = g_hash_table_lookup(oh_sessions.table, &sid); if (!session) { g_static_rec_mutex_unlock(&oh_sessions.lock); return SA_ERR_HPI_INVALID_SESSION; } eventq = session->eventq; g_async_queue_ref(eventq); g_static_rec_mutex_unlock(&oh_sessions.lock); if (timeout == SAHPI_TIMEOUT_IMMEDIATE) { devent = g_async_queue_try_pop(eventq); } else if (timeout == SAHPI_TIMEOUT_BLOCK) { devent = g_async_queue_pop(eventq); /* FIXME: Need to time this. */ } else { g_get_current_time(&gfinaltime); g_time_val_add(&gfinaltime, (glong) (timeout / 1000)); devent = g_async_queue_timed_pop(eventq, &gfinaltime); } g_async_queue_unref(eventq); if (devent) { memcpy(event, devent, sizeof(struct oh_event)); g_free(devent); return SA_OK; } else { memset(event, 0, sizeof(struct oh_event)); return SA_ERR_HPI_TIMEOUT; } }
static gpointer worker_thread(gpointer data) { //TODO consider replacing the main loop with a blocking call on the async queue, //(g_async_queue_pop) waiting for messages. dbg(1, "new worker thread."); g_async_queue_ref(msg_queue); bool done(gpointer _message) { Message* message = _message; message->done(message->sample, message->user_data); send_progress(GINT_TO_POINTER(g_list_length(msg_list))); sample_unref(message->sample); g_free(message); return G_SOURCE_REMOVE; }
int Action::run_all( GAsyncQueue * queue ) { g_assert( queue ); int result = 0; g_async_queue_ref( queue ); while ( Action * action = ( Action * ) g_async_queue_try_pop( queue ) ) { run_internal( action ); delete action; ++result; } g_async_queue_unref( queue ); return result; }
static gpointer worker_thread(gpointer data) { dbg(2, "new file load thread."); WfWorker* w = data; g_return_val_if_fail(w->msg_queue, NULL); g_async_queue_ref(w->msg_queue); // check for new work while(true){ QueueItem* job = g_async_queue_pop(w->msg_queue); // blocking dbg(2, "starting new job: %p", job); Waveform* waveform = g_weak_ref_get(&job->ref); if(waveform){ if(!job->cancelled){ // note that the job is run directly so that it runs in the worker thread. job->work(waveform, job->user_data); } g_idle_add(worker_unref_waveform, waveform); } g_timeout_add(1, worker_post, WF_NEW(WorkerJob, .job = job, .worker = w ) ); g_usleep(100); } return NULL; }
void ManglerAudio::output(void) {/*{{{*/ ManglerPCM *queuedpcm = NULL; if (!pcm_queue) { return; } g_async_queue_ref(pcm_queue); for (;;) { if (stop_output || (check_loggedin && !v3_is_loggedin())) { close(); break; } if (buffer) { buffer--; ManglerPCM *bufferpcm = (ManglerPCM *)g_async_queue_pop(pcm_queue); if (bufferpcm && bufferpcm->length) { uint32_t prelen = (queuedpcm) ? queuedpcm->length : 0; uint32_t buflen = prelen + bufferpcm->length; uint8_t *bufpcm = (uint8_t *)malloc(buflen); memcpy(bufpcm + prelen, bufferpcm->sample, bufferpcm->length); if (queuedpcm) { memcpy(bufpcm, queuedpcm->sample, queuedpcm->length); delete queuedpcm; } delete bufferpcm; queuedpcm = new ManglerPCM(buflen, bufpcm); free(bufpcm); continue; } else { buffer = 0; finish(); } } if (!queuedpcm) { queuedpcm = (ManglerPCM *)g_async_queue_pop(pcm_queue); } // finish() queues a 0 length packet to notify us that we're done if (!queuedpcm->length) { close(true); break; } if (mangler->muteSound) { delete queuedpcm; queuedpcm = NULL; continue; } if (Mangler::config["AudioSubsystem"].toLower() != backend->getAudioSubsystem()) { if (!switchBackend(Mangler::config["AudioSubsystem"].toLower()) || !open()) { break; } } if (!backend->write(queuedpcm->sample, queuedpcm->length, channels)) { close(); break; } delete queuedpcm; queuedpcm = NULL; } outputStreamOpen = false; close(); while (queuedpcm || (queuedpcm = (ManglerPCM *)g_async_queue_try_pop(pcm_queue))) { delete queuedpcm; queuedpcm = NULL; } g_async_queue_unref(pcm_queue); delete this; return; }/*}}}*/
QueueRunAllAction( GAsyncQueue * _queue ) : queue( g_async_queue_ref( _queue ) ) {}
static void *zbar_gtk_processing_thread (void *arg) { ZBarGtk *self = ZBAR_GTK(arg); if(!self->_private) return(NULL); ZBarGtkPrivate *zbar = ZBAR_GTK_PRIVATE(self->_private); g_object_ref(zbar); g_assert(zbar->queue); g_async_queue_ref(zbar->queue); zbar->scanner = zbar_image_scanner_create(); g_assert(zbar->scanner); /* thread side enabled state */ gboolean video_enabled = FALSE; GValue *msg = NULL; while(TRUE) { if(!msg) msg = g_async_queue_pop(zbar->queue); g_assert(G_IS_VALUE(msg)); GType type = G_VALUE_TYPE(msg); if(type == G_TYPE_INT) { /* video state change */ int state = g_value_get_int(msg); if(state < 0) { /* terminate processing thread */ g_value_unset(msg); g_free(msg); msg = NULL; break; } g_assert(state >= 0 && state <= 1); video_enabled = (state != 0); } else if(type == G_TYPE_STRING) { /* open new video device */ const char *video_device = g_value_get_string(msg); video_enabled = zbar_gtk_video_open(self, video_device); } else if(type == GDK_TYPE_PIXBUF) { /* scan provided image and broadcast results */ zbar_image_t *image = zbar_image_create(); GdkPixbuf *pixbuf = GDK_PIXBUF(g_value_dup_object(msg)); if(zbar_gtk_image_from_pixbuf(image, pixbuf)) zbar_gtk_process_image(self, image); else g_object_unref(pixbuf); zbar_image_destroy(image); } else { gchar *dbg = g_strdup_value_contents(msg); g_warning("unknown message type (%x) passed to thread: %s\n", (unsigned)type, dbg); g_free(dbg); } g_value_unset(msg); g_free(msg); msg = NULL; if(video_enabled) { /* release reference to any previous pixbuf */ zbar_window_draw(zbar->window, NULL); if(zbar_video_enable(zbar->video, 1)) { zbar_video_error_spew(zbar->video, 0); video_enabled = FALSE; continue; } zbar_image_scanner_enable_cache(zbar->scanner, 1); while(video_enabled && !(msg = g_async_queue_try_pop(zbar->queue))) { zbar_image_t *image = zbar_video_next_image(zbar->video); if(zbar_gtk_process_image(self, image) < 0) video_enabled = FALSE; if(image) zbar_image_destroy(image); } zbar_image_scanner_enable_cache(zbar->scanner, 0); if(zbar_video_enable(zbar->video, 0)) { zbar_video_error_spew(zbar->video, 0); video_enabled = FALSE; } /* release video image and revert to logo */ if(zbar->window) { zbar_window_draw(zbar->window, NULL); gtk_widget_queue_draw(GTK_WIDGET(self)); } if(!video_enabled) /* must have been an error while streaming */ zbar_gtk_video_open(self, NULL); } } if(zbar->window) zbar_window_draw(zbar->window, NULL); g_object_unref(zbar); return(NULL); }
static void do_thread_job(mb_btreplay_thread_arg_t *arg) { int fd; int open_flags; mb_btreplay_ioreq_t *ioreq; int64_t endpos; int64_t ofst; size_t sz; void *buf; size_t bufsz; open_flags = O_RDWR; if (option.direct){ open_flags |= O_DIRECT; } if (-1 == (fd = open(option.target_path, open_flags))){ perror("Failed open(2)"); exit(EXIT_FAILURE); } endpos = -1; bufsz = 64 * KIBI; buf = memalign(KIBI, bufsz); g_async_queue_ref(arg->ioreq_queue); for(;;) { ioreq = (mb_btreplay_ioreq_t *) g_async_queue_pop(arg->ioreq_queue); if (ioreq->stop == true) { if (option.verbose) fprintf(stderr, "[tid: %d] stopping...\n", arg->tid); free(ioreq); break; } int act = ioreq->trace.action & 0xffff; bool w = (ioreq->trace.action & BLK_TC_ACT(BLK_TC_WRITE)) != 0; if (act == __BLK_TA_ISSUE) { ofst = ioreq->trace.sector * 512; sz = ioreq->trace.bytes; if (sz > bufsz) { free(buf); bufsz = sz; buf = memalign(KIBI, bufsz); } if (ofst != endpos) { if (-1 == lseek64(fd, ofst, SEEK_SET)) { fprintf(stderr, "lseek64 failed: errno=%d\n", errno); } if (option.vverbose) printf("[tid: %d] lseek64 to %ld\n", arg->tid, ofst); } if (option.vverbose) printf("[tid: %d] %s on fd:%d at %ld + %ld\n", arg->tid, (w == true ? "write" : "read"), fd, ofst, sz); if (w == false) { // do read mb_readall(fd, buf, sz, true); } else { // do write mb_writeall(fd, buf, sz, true); } endpos = ofst + sz; } free(ioreq); } close(fd); }
/*! \brief thread_dispatcher() runs continuously as a thread listening to the io_data_queue and running handlers as messages come in. After they are done it passes the message back to the gui via the dispatch_queue for further gui handling (for things that can't run in a thread context) \param data is unused */ G_MODULE_EXPORT void *thread_dispatcher(gpointer data) { GThread * repair_thread = NULL; Serial_Params *serial_params = NULL; Io_Message *message = NULL; GAsyncQueue *io_data_queue = NULL; CmdLineArgs *args = NULL; void *(*network_repair_thread)(gpointer data) = NULL; void *(*serial_repair_thread)(gpointer data) = NULL; /* GTimer *clock;*/ ENTER(); io_data_queue = (GAsyncQueue *)DATA_GET(global_data,"io_data_queue"); serial_params = (Serial_Params *)DATA_GET(global_data,"serial_params"); get_symbol("serial_repair_thread",(void **)&serial_repair_thread); args = (CmdLineArgs *)DATA_GET(global_data,"args"); if (args->network_mode) get_symbol("network_repair_thread",(void **)&network_repair_thread); g_return_val_if_fail(args,NULL); g_return_val_if_fail(io_data_queue,NULL); g_return_val_if_fail(serial_params,NULL); g_async_queue_ref(io_data_queue); /* clock = g_timer_new();*/ /* Endless Loop, wait for message, processs and repeat... */ while (TRUE) { if (DATA_GET(global_data,"thread_dispatcher_exit")) { fast_exit: /* drain queue and exit thread */ while ((message = (Io_Message *)g_async_queue_try_pop(io_data_queue)) != NULL) dealloc_io_message(message); g_async_queue_unref(io_data_queue); EXIT(); g_thread_exit(0); } message = (Io_Message *)g_async_queue_timeout_pop(io_data_queue,1000000); if (!message) /* NULL message */ { MTXDBG(THREADS|IO_MSG,_("No message received...\n")); continue; } else MTXDBG(THREADS|IO_MSG,_("MESSAGE ARRIVED on IO queue...\n")); if ((!DATA_GET(global_data,"offline")) && (((!DATA_GET(global_data,"connected")) && (serial_params->open)) || (!(serial_params->open)))) { /*printf("somehow somethign went wrong, connected is %i, offline is %i, serial_params->open is %i\n",DATA_GET(global_data,"connected"),DATA_GET(global_data,"offline"),serial_params->open);*/ if (args->network_mode) { MTXDBG(THREADS,_("LINK DOWN, Initiating NETWORK repair thread!\n")); repair_thread = g_thread_new("Network Repair thread",network_repair_thread,NULL); } else { MTXDBG(THREADS,_("LINK DOWN, Initiating serial repair thread!\n")); repair_thread = g_thread_new("Serial Repair thread",serial_repair_thread,NULL); } g_thread_join(repair_thread); } if ((!serial_params->open) && (!DATA_GET(global_data,"offline"))) { MTXDBG(THREADS,_("LINK DOWN, Can't process requested command, aborting call\n")); thread_update_logbar("comm_view","warning",g_strdup("Disconnected Serial Link. Check Communications link/cable...\n"),FALSE,FALSE); thread_update_widget("titlebar",MTX_TITLE,g_strdup("Disconnected link, check Communications tab...")); message->status = FALSE; continue; } switch ((CmdType)message->command->type) { case FUNC_CALL: if (!message->command->function) MTXDBG(CRITICAL|THREADS,_("CRITICAL ERROR, function \"%s()\" is not found!!\n"),message->command->func_call_name); else { /*printf("Calling FUNC_CALL, function \"%s()\" \n",message->command->func_call_name);*/ message->status = message->command->function(message->command,message->command->func_call_arg); /* if (!result) message->command->defer_post_functions=TRUE; */ } break; case WRITE_CMD: /*g_timer_start(clock);*/ message->status = write_data(message); if (!message->status) DATA_SET(global_data,"connected",GINT_TO_POINTER(FALSE)); /*printf("Write command elapsed time %f\n",g_timer_elapsed(clock,NULL));*/ if (message) { if (message->command) { if (message->command->helper_function) { message->command->helper_function(message, message->command->helper_func_arg); } } } /*printf("Write command with post function time %f\n",g_timer_elapsed(clock,NULL));*/ break; case NULL_CMD: /*printf("null_cmd, just passing thru\n");*/ break; default: MTXDBG(THREADS|CRITICAL,_("Hit default case, this SHOULD NOT HAPPEN it's a bug, notify author! \n")); break; } /* If set to defer post functions, it means they were passed via a function fall, thus dealloc it here., Otherwise push up the queue to the postfunction dispatcher */ if (message->command->defer_post_functions) dealloc_io_message(message); else g_idle_add(process_pf_message,message); } EXIT(); return 0; }
/* This function is executed in the main thread, decides the * module that's going to be run for a given task, and dispatches * the task according to the threading strategy of that module. */ static gboolean dispatch_task_cb (TrackerExtractTask *task) { TrackerModuleThreadAwareness thread_awareness; TrackerExtractPrivate *priv; GError *error = NULL; GModule *module; #ifdef THREAD_ENABLE_TRACE g_debug ("Thread:%p (Main) <-- File:'%s' - Dispatching\n", g_thread_self (), task->file); #endif /* THREAD_ENABLE_TRACE */ priv = TRACKER_EXTRACT_GET_PRIVATE (task->extract); if (!task->mimetype) { error = g_error_new (TRACKER_DBUS_ERROR, 0, "No mimetype for '%s'", task->file); } else { if (!task->mimetype_handlers) { /* First iteration for task, get the mimetype handlers */ task->mimetype_handlers = tracker_extract_module_manager_get_mimetype_handlers (task->mimetype); if (!task->mimetype_handlers) { error = g_error_new (TRACKER_DBUS_ERROR, 0, "No mimetype extractor handlers for uri:'%s' and mime:'%s'", task->file, task->mimetype); } } else { /* Any further iteration, should happen rarely if * most specific handlers know nothing about the file */ g_message ("Trying next extractor for '%s'", task->file); if (!tracker_mimetype_info_iter_next (task->mimetype_handlers)) { g_message (" There's no next extractor"); error = g_error_new (TRACKER_DBUS_ERROR, 0, "Could not get any metadata for uri:'%s' and mime:'%s'", task->file, task->mimetype); } } } if (error) { g_simple_async_result_set_from_error ((GSimpleAsyncResult *) task->res, error); g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res); extract_task_free (task); g_error_free (error); return FALSE; } task->cur_module = module = tracker_mimetype_info_get_module (task->mimetype_handlers, &task->cur_func, &thread_awareness); if (!module || !task->cur_func) { g_warning ("Discarding task with no module '%s'", task->file); priv->unhandled_count++; return FALSE; } g_mutex_lock (&priv->task_mutex); priv->running_tasks = g_list_prepend (priv->running_tasks, task); g_mutex_unlock (&priv->task_mutex); switch (thread_awareness) { case TRACKER_MODULE_NONE: /* Error out */ g_simple_async_result_set_error ((GSimpleAsyncResult *) task->res, TRACKER_DBUS_ERROR, 0, "Module '%s' initialization failed", g_module_name (module)); g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res); extract_task_free (task); break; case TRACKER_MODULE_MAIN_THREAD: /* Dispatch the task right away in this thread */ g_message ("Dispatching '%s' in main thread", task->file); get_metadata (task); break; case TRACKER_MODULE_SINGLE_THREAD: { GAsyncQueue *async_queue; async_queue = g_hash_table_lookup (priv->single_thread_extractors, module); if (!async_queue) { GThread *thread; /* No thread created yet for this module, create it * together with the async queue used to pass data to it */ async_queue = g_async_queue_new (); thread = g_thread_try_new ("single", (GThreadFunc) single_thread_get_metadata, g_async_queue_ref (async_queue), &error); if (!thread) { g_simple_async_result_take_error ((GSimpleAsyncResult *) task->res, error); g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res); extract_task_free (task); return FALSE; } /* We won't join the thread, so just unref it here */ g_object_unref (thread); g_hash_table_insert (priv->single_thread_extractors, module, async_queue); } g_async_queue_push (async_queue, task); break; } case TRACKER_MODULE_MULTI_THREAD: /* Put task in thread pool */ g_message ("Dispatching '%s' in thread pool", task->file); g_thread_pool_push (priv->thread_pool, task, &error); if (error) { g_simple_async_result_set_from_error ((GSimpleAsyncResult *) task->res, error); g_simple_async_result_complete_in_idle ((GSimpleAsyncResult *) task->res); extract_task_free (task); g_error_free (error); return FALSE; } break; } return FALSE; }
/** * Thread which process addresses on tls push queue (tls_push_queue member * of ::nuauthdatas) which need an authentication. * * Lock is only needed when modifications are done, because when this thread * work (push mode) it's the only one who can modify the hash. * * Use a switch: * - #WARN_MESSAGE: call warn_clients() (and may call ip_authentication_workers()) * - #INSERT_MESSAGE: call add_client() */ void *push_worker(GMutex * mutex) { struct msg_addr_set *global_msg = g_new0(struct msg_addr_set, 1); struct nu_srv_message *msg = g_new0(struct nu_srv_message, 1); struct internal_message *message; GTimeVal tv; msg->type = SRV_REQUIRED_PACKET; msg->option = 0; msg->length = htons(4); global_msg->msg = msg; g_async_queue_ref(nuauthdatas->tls_push_queue); /* wait for message */ while (g_mutex_trylock(mutex)) { g_mutex_unlock(mutex); /* wait a message during POP_DELAY */ g_get_current_time(&tv); g_time_val_add(&tv, POP_DELAY); message = g_async_queue_timed_pop(nuauthdatas->tls_push_queue, &tv); if (message == NULL) continue; switch (message->type) { case WARN_MESSAGE: global_msg->addr = (((auth_pckt_t *) message->datas)->header).saddr; global_msg->found = FALSE; /* search in client array */ warn_clients(global_msg, NULL, NULL); /* do we have found something */ if (!ipv6_equal(&global_msg->addr, &in6addr_any)) { if (global_msg->found == FALSE) { /* if we do ip authentication send request to pool */ if (nuauthconf-> do_ip_authentication) { thread_pool_push (nuauthdatas-> ip_authentication_workers, message->datas, NULL); } else { g_free(message->datas); } } else { /* free header */ g_free(message->datas); } } break; case INSERT_MESSAGE: { struct tls_insert_data *data = message->datas; if (data->data) { add_client(data->socket, data->data); } g_free(data); } break; default: g_message("lost"); } g_free(message); } g_free(msg); g_free(global_msg); g_async_queue_unref(nuauthdatas->tls_push_queue); return NULL; }
/*! \brief This functions handles all incoing data from the ECU and validates its content for proper START/STOP/ESCAPING and allocates a FreeEMS_Packet structure for VALID packets and populates the required fields as needed \param buf is a pointer to the incoming data buffer \param len is the numbe of bytes to pull from the incoming buffer */ G_MODULE_EXPORT void handle_data(guchar *buf, gint len) { static GAsyncQueue *queue = NULL; /* Statistic collection variables */ static guchar packetBuffer[3000]; static unsigned int packets = 0; static unsigned int charsDropped = 0; static unsigned int badChecksums = 0; static unsigned int badPackets = 0; static unsigned int goodChecksums = 0; static unsigned int startsInsidePacket = 0; static unsigned int totalFalseStartLost = 0; static unsigned int doubleStartByteOccurances = 0; static unsigned int strayDataBytesOccurances = 0; static unsigned int escapeBytesFound = 0; static unsigned int escapedStopBytesFound = 0; static unsigned int escapedStartBytesFound = 0; static unsigned int escapedEscapeBytesFound = 0; static unsigned int escapePairMismatches = 0; static unsigned long sumOfGoodPacketLengths = 0; /* Loop and state variables */ static gboolean insidePacket = FALSE; static gboolean unescapeNext = FALSE; static unsigned int processed = 0; static unsigned char checksum = 0; static unsigned char lastChar = 0; static unsigned int currentPacketLength = 0; guchar character; gint i = 0; FreeEMS_Packet *packet = NULL; if (!queue) queue = (GAsyncQueue *)DATA_GET(global_data,"packet_queue"); log_inbound_data_f(buf,len); for (i=0;i<len;i++) { character = buf[i]; if (character == START_BYTE) { if (insidePacket) { startsInsidePacket++; if (currentPacketLength == 0) { doubleStartByteOccurances++; } else { totalFalseStartLost += currentPacketLength; strayDataBytesOccurances++; } } insidePacket = TRUE; checksum = 0; currentPacketLength = 0; } else if (insidePacket) { if (unescapeNext) { /* Clear escaped byte next flag */ unescapeNext = FALSE; if (character == ESCAPED_ESCAPE_BYTE) { checksum += ESCAPE_BYTE; lastChar = ESCAPE_BYTE; escapedEscapeBytesFound++; packetBuffer[currentPacketLength] = ESCAPE_BYTE; currentPacketLength++; } else if (character == ESCAPED_START_BYTE) { /* Store and checksum start byte */ checksum += START_BYTE; lastChar = START_BYTE; escapedStartBytesFound++; packetBuffer[currentPacketLength] = START_BYTE; currentPacketLength++; } else if(character == ESCAPED_STOP_BYTE) { /* Store and checksum stop byte */ checksum += STOP_BYTE; lastChar = STOP_BYTE; escapedStopBytesFound++; packetBuffer[currentPacketLength] = STOP_BYTE; currentPacketLength++; }else { /* Otherwise reset and record as data is bad */ insidePacket = FALSE; checksum = 0; currentPacketLength = 0; escapePairMismatches++; } } else if (character == ESCAPE_BYTE) { /* Set flag to indicate that the next byte should be un-escaped. */ unescapeNext = TRUE; escapeBytesFound++; } else if (character == STOP_BYTE) { packets++; /* Bring the checksum back to where it should be */ checksum -= lastChar; /* Check that the checksum matches */ if(checksum != lastChar) { badChecksums++; printf("Packet number %u ending of length %u at char number %u failed checksum! Received %u Calculated %u\n", packets, currentPacketLength, processed, lastChar, checksum); } else { goodChecksums++; /* Add the length to the SUM */ sumOfGoodPacketLengths += currentPacketLength; /* Clear the state */ packet = g_new0(FreeEMS_Packet, 1); packet->data = (guchar *)g_memdup(packetBuffer,currentPacketLength); packet->raw_length = currentPacketLength; mtxlog_packet(packet->data,packet->raw_length,FALSE); if (!packet_decode(packet)) { printf("Packet fields don't make sense!\n"); freeems_packet_cleanup(packet); badPackets++; } else if (queue) { g_async_queue_ref(queue); g_async_queue_push(queue,(gpointer)packet); g_async_queue_unref(queue); } else printf("packet queue not found!?!!\n"); } insidePacket = FALSE; currentPacketLength= 0; checksum = 0; } else { /* If it isn't special checksum it! */ checksum += character; lastChar = character; packetBuffer[currentPacketLength] = character; currentPacketLength++; } } else charsDropped++; } }
void threadLoop(gpointer data) { GAsyncQueue *privCommandQueue = g_async_queue_ref(((OBD2Source*)data)->commandQueue); GAsyncQueue *privResponseQueue = g_async_queue_ref(((OBD2Source*)data)->responseQueue); GAsyncQueue *privSingleShotQueue = g_async_queue_ref(((OBD2Source*)data)->singleShotQueue); GAsyncQueue *privSubscriptionAddQueue = g_async_queue_ref(((OBD2Source*)data)->subscriptionAddQueue); GAsyncQueue *privSubscriptionRemoveQueue = g_async_queue_ref(((OBD2Source*)data)->subscriptionRemoveQueue); GAsyncQueue *privStatusQueue = g_async_queue_ref(((OBD2Source*)data)->statusQueue); obdLib *obd = new obdLib(); OBD2Source *source = (OBD2Source*)data; obd->setCommsCallback([](const char* mssg, void* data) { DebugOut(6)<<mssg<<endl; },NULL); obd->setDebugCallback([](const char* mssg, void* data, obdLib::DebugLevel debugLevel) { DebugOut(debugLevel)<<mssg<<endl; },NULL); std::list<ObdPid*> reqList; std::list<ObdPid*> repeatReqList; ObdPid::ByteArray replyVector; std::string reply; std::string port; std::string baud; bool connected=false; int emptycount = 0; int timeoutCount = 0; while (source->m_threadLive) { //gpointer query = g_async_queue_pop(privCommandQueue); gpointer query = g_async_queue_try_pop(privSingleShotQueue); if (query != nullptr) { //printf("Got request!\n"); ObdPid *req = (ObdPid*)query; DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got single shot request: " << req->pid.substr(0,req->pid.length()-1) << ":" << req->property <<endl; repeatReqList.push_back(req); } query = g_async_queue_try_pop(privSubscriptionAddQueue); if (query != nullptr) { ObdPid *req = (ObdPid*)query; //DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got subscription request for "<<req->req<<endl; reqList.push_back(req); } query = g_async_queue_try_pop(privCommandQueue); if (query != nullptr) { //ObdPid *req = (ObdPid*)query; CommandRequest *req = (CommandRequest*)query; //commandMap[req->req] = req->arg; //printf("Command: %s\n",req->req.c_str()); DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Command:" << req->req << endl; if (req->req == "connect" ) { if (source->m_isBluetooth) { BluetoothDevice bt; std::string tempPort = bt.getDeviceForAddress(source->m_btDeviceAddress, source->m_btAdapterAddress); if(tempPort != "") { DebugOut(3)<<"Using bluetooth device \""<<source->m_btDeviceAddress<<"\" bound to: "<<tempPort<<endl; port = tempPort; } } else { port = req->arglist[0]; baud = req->arglist[1]; } connected = connect(obd,port,baud); if(connected) { StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "connected"; g_async_queue_push(privStatusQueue,statusreq); } else { StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "disconnected"; g_async_queue_push(privStatusQueue,statusreq); } } else if (req->req == "connectifnot") { if (!connected) { if (source->m_isBluetooth) { BluetoothDevice bt; std::string tempPort = bt.getDeviceForAddress(source->m_btDeviceAddress, source->m_btAdapterAddress); if(tempPort != "") { DebugOut(3)<<"Using bluetooth device \""<<source->m_btDeviceAddress<<"\" bound to: "<<tempPort<<endl; port = tempPort; } else { DebugOut(DebugOut::Error)<<"Error creating bluetooth device"<<endl; continue; } } connected = connect(obd,port,baud); if(connected) { StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "connected"; g_async_queue_push(privStatusQueue,statusreq); } else { StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "disconnected"; g_async_queue_push(privStatusQueue,statusreq); } } } else if (req->req == "setportandbaud") { port = req->arglist[0]; baud = req->arglist[1]; } else if (req->req == "disconnect") { DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Using queued disconnect" << (ulong)req << endl; obd->closePort(); BluetoothDevice bt; bt.disconnect(source->m_btDeviceAddress, source->m_btAdapterAddress); connected = false; StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "disconnected"; g_async_queue_push(privStatusQueue,statusreq); } delete req; } query = g_async_queue_try_pop(privSubscriptionRemoveQueue); if (query != nullptr) { DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Got unsubscription request"<<endl; ObdPid *req = (ObdPid*)query; for (std::list<ObdPid*>::iterator i=reqList.begin();i!= reqList.end();i++) { if ((*i)->property == req->property) { reqList.erase(i); delete (*i); i--; if (reqList.size() == 0) { break; } } } //reqList.push_back(req->req); delete req; } if (reqList.size() > 0 && !connected) { /*CommandRequest *req = new CommandRequest(); req->req = "connect"; req->arglist.push_back(port); req->arglist.push_back(baud); g_async_queue_push(privCommandQueue,req); continue;*/ } else if (reqList.size() == 0 && connected) { emptycount++; if (emptycount < 1000) { usleep(10000); continue; } emptycount = 0; CommandRequest *req = new CommandRequest(); req->req = "disconnect"; g_async_queue_push(privCommandQueue,req); continue; } if (!connected) { usleep(10000); continue; } for (std::list<ObdPid*>::iterator i=reqList.begin();i!= reqList.end();i++) { repeatReqList.push_back(*i); } int badloop = 0; for (std::list<ObdPid*>::iterator i=repeatReqList.begin();i!= repeatReqList.end();i++) { DebugOut(10) << __SMALLFILE__ << ":" << __LINE__ << "Requesting pid: " << (*i)->pid.substr(0,(*i)->pid.length()-1) << (*i)->property << endl; if (source->m_blacklistPidCountMap.find((*i)->pid) != source->m_blacklistPidCountMap.end()) { //Don't erase the pid, just skip over it. int count = (*source->m_blacklistPidCountMap.find((*i)->pid)).second; if (count > 10) { continue; } } badloop++; bool result = false; if(beginsWith((*i)->pid,"AT") || beginsWith((*i)->pid, "ST")) { result = obd->sendObdRequestString((*i)->pid.c_str(),(*i)->pid.length(),&replyVector); } else result = obd->sendObdRequestString((*i)->pid.c_str(),(*i)->pid.length(),&replyVector,5,3); if (!result) { //This only happens during a error with the com port. Close it and re-open it later. DebugOut() << __SMALLFILE__ <<":"<< __LINE__ << "Unable to send request:" << (*i)->pid.substr(0,(*i)->pid.length()-1) << endl; if (obd->lastError() == obdLib::NODATA) { DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "OBDLib::NODATA for pid" << (*i)->pid.substr(0,(*i)->pid.length()-1) << " expected property: " << (*i)->property << endl; if (source->m_blacklistPidCountMap.find((*i)->pid) != source->m_blacklistPidCountMap.end()) { //pid value i not yet in the list. int count = (*source->m_blacklistPidCountMap.find((*i)->pid)).second; if (count > 10) { } source->m_blacklistPidCountMap.erase(source->m_blacklistPidCountMap.find((*i)->pid)); source->m_blacklistPidCountMap.insert(pair<std::string,int>((*i)->pid,count)); } else { source->m_blacklistPidCountMap.insert(pair<std::string,int>((*i)->pid,1)); } StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "error:nodata"; statusreq->property = (*i)->property; g_async_queue_push(privStatusQueue,statusreq); continue; } else if (obd->lastError() == obdLib::TIMEOUT) { timeoutCount++; if (timeoutCount < 2) { DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "OBDLib::TIMEOUT for pid" << (*i)->pid << endl; StatusMessage *statusreq = new StatusMessage(); statusreq->statusStr = "error:timeout"; g_async_queue_push(privStatusQueue,statusreq); continue; } } else { DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "OBD Other error:" << obd->lastError() << endl; } CommandRequest *req = new CommandRequest(); DebugOut() << __SMALLFILE__ << ":" << __LINE__ << "Queuing up a disconnect" << (ulong)req << endl; req->req = "disconnect"; g_async_queue_push(privCommandQueue,req); i = repeatReqList.end(); i--; continue; } if (source->m_blacklistPidCountMap.find((*i)->pid) != source->m_blacklistPidCountMap.end()) { //If we get the pid response, then we want to clear out the blacklist list. source->m_blacklistPidCountMap.erase(source->m_blacklistPidCountMap.find((*i)->pid)); } timeoutCount = 0; //ObdPid *pid = ObdPid::pidFromReply(replyVector); ObdPid *pid = obd2AmbInstance->createPidFromReply(replyVector); if (!pid) { //Invalid reply DebugOut() << "Invalid reply"<<endl; continue; } else { DebugOut(11) << __SMALLFILE__ <<":"<< __LINE__ << "Reply recieved and queued for:" << (*i)->pid.substr(0,(*i)->pid.length()-1) << endl; std::string repstr; for (int i=0;i<replyVector.size();i++) { if (replyVector[i] != 13) { repstr += (char)replyVector[i]; } //DebugOut(11) << replyVector[i]; } DebugOut(11) << "Reply:" << repstr << endl; } g_async_queue_push(privResponseQueue,pid); } if (badloop == 0) { //We had zero non-blacklisted events. Pause for a moment here to keep from burning CPU. //usleep(10000); } repeatReqList.clear(); } if (connected) { obd->closePort(); } }
/*! \brief signal_read_rtvars_thread() is thread which fires off the read msg to get a new set of realtime variables. It does so by queing messages to a thread which handles I/O. This function will check the queue depth and if the queue is backed up it will skip sending a request for data, as that will only aggravate the queue roadblock. \param data is unused \returns 0 on signal to exit */ G_MODULE_EXPORT void * signal_read_rtvars_thread(gpointer data) { static void (*signal_read_rtvars)(void); static gboolean (*setup_rtv)(void); Serial_Params *serial_params; GMutex * mutex = g_mutex_new(); GTimeVal time; GAsyncQueue *io_data_queue = NULL; GAsyncQueue *pf_dispatch_queue = NULL; GCond *rtv_thread_cond = NULL; GMutex *rtv_thread_mutex = NULL; gint count = 0; gint io_queue_len = 0; gint pf_queue_len = 0; gint delay = 0; g_mutex_lock(mutex); serial_params = (Serial_Params *)DATA_GET(global_data,"serial_params"); io_data_queue = (GAsyncQueue *)DATA_GET(global_data,"io_data_queue"); pf_dispatch_queue = (GAsyncQueue *)DATA_GET(global_data,"pf_dispatch_queue"); rtv_thread_cond = (GCond *)DATA_GET(global_data,"rtv_thread_cond"); rtv_thread_mutex = (GMutex *)DATA_GET(global_data,"rtv_thread_mutex"); get_symbol("signal_read_rtvars",(void **)&signal_read_rtvars); get_symbol("setup_rtv",(void **)&setup_rtv); g_return_val_if_fail(serial_params,NULL); g_return_val_if_fail(signal_read_rtvars,NULL); g_return_val_if_fail(io_data_queue,NULL); g_return_val_if_fail(pf_dispatch_queue,NULL); g_return_val_if_fail(rtv_thread_cond,NULL); g_return_val_if_fail(rtv_thread_mutex,NULL); g_return_val_if_fail(setup_rtv,NULL); if (!setup_rtv()) { g_mutex_unlock(mutex); g_mutex_free(mutex); g_thread_exit(NULL); } g_async_queue_ref(io_data_queue); g_async_queue_ref(pf_dispatch_queue); g_mutex_lock(rtv_thread_mutex); while (TRUE) { MTXDBG(IO_MSG|THREADS,_("Sending message to thread to read RT vars\n")); signal_read_rtvars(); count = 0; /* Auto-throttling if gui gets sluggish */ while ((g_async_queue_length(io_data_queue) > 2) || (g_async_queue_length(pf_dispatch_queue) > 3)) { count++; pf_queue_len = g_async_queue_length(pf_dispatch_queue); io_queue_len = g_async_queue_length(io_data_queue); //printf("Auto-throttling, io queue length %i, pf queue length %i, loop iterations %i\n",io_queue_len,pf_queue_len,count); g_get_current_time(&time); delay = MAX(io_queue_len,pf_queue_len); g_time_val_add(&time,10000*(delay)); //printf("io_queue_len is %i pf queue length is %i, delay is %i\n",io_queue_len,pf_queue_len,delay ); if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time)) goto breakout; } g_get_current_time(&time); //printf("serial_params->read_wait is %i\n",serial_params->read_wait); g_time_val_add(&time,serial_params->read_wait*1000); if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time)) goto breakout; } breakout: g_async_queue_unref(io_data_queue); g_async_queue_unref(pf_dispatch_queue); g_mutex_unlock(mutex); g_mutex_free(mutex); g_mutex_unlock(rtv_thread_mutex); g_thread_exit(0); return NULL; }
/** * oh_dequeue_session_event * @sid: * @event: * * * * Returns: **/ SaErrorT oh_dequeue_session_event(SaHpiSessionIdT sid, SaHpiTimeoutT timeout, struct oh_event * event, SaHpiEvtQueueStatusT * eventq_status) { struct oh_session *session = NULL; struct oh_event *devent = NULL; GTimeVal gfinaltime; GAsyncQueue *eventq = NULL; SaHpiBoolT subscribed; SaErrorT invalid; if (sid < 1 || (event == NULL)) return SA_ERR_HPI_INVALID_PARAMS; wrap_g_static_rec_mutex_lock(&oh_sessions.lock); /* Locked session table */ session = g_hash_table_lookup(oh_sessions.table, &sid); if (!session) { wrap_g_static_rec_mutex_unlock(&oh_sessions.lock); return SA_ERR_HPI_INVALID_SESSION; } if (eventq_status) { *eventq_status = session->eventq_status; } session->eventq_status = 0; eventq = session->eventq; g_async_queue_ref(eventq); wrap_g_static_rec_mutex_unlock(&oh_sessions.lock); if (timeout == SAHPI_TIMEOUT_IMMEDIATE) { devent = g_async_queue_try_pop(eventq); } else if (timeout == SAHPI_TIMEOUT_BLOCK) { while (devent == NULL) { g_get_current_time(&gfinaltime); g_time_val_add(&gfinaltime, 5000000L); devent = wrap_g_async_queue_timed_pop(eventq, &gfinaltime); /* compliance with spec page 63 */ invalid = oh_get_session_subscription(sid, &subscribed); /* Is the session still open? or still subscribed? */ if (invalid || !subscribed) { g_async_queue_unref(eventq); oh_event_free(devent, FALSE); return invalid ? SA_ERR_HPI_INVALID_SESSION : SA_ERR_HPI_INVALID_REQUEST; } } } else { g_get_current_time(&gfinaltime); g_time_val_add(&gfinaltime, (glong) (timeout / 1000)); devent = wrap_g_async_queue_timed_pop(eventq, &gfinaltime); invalid = oh_get_session_subscription(sid, &subscribed); if (invalid || !subscribed) { g_async_queue_unref(eventq); oh_event_free(devent, FALSE); return invalid ? SA_ERR_HPI_INVALID_SESSION : SA_ERR_HPI_INVALID_REQUEST; } } g_async_queue_unref(eventq); if (devent) { int cc; cc = oh_detect_quit_event(devent); if (cc == 0) { // OpenHPI is about to quit oh_event_free(devent, FALSE); return SA_ERR_HPI_NO_RESPONSE; } memcpy(event, devent, sizeof(struct oh_event)); g_free(devent); return SA_OK; } else { memset(event, 0, sizeof(struct oh_event)); return SA_ERR_HPI_TIMEOUT; } }
void emulate_thread(gpointer data, gpointer user_data) { struct emu_emulate_ctx *ctx = user_data; struct emu_config *conf = ctx->config; struct emu *e = ctx->emu; struct emu_env *env = ctx->env; int ret; g_mutex_lock(&ctx->mutex); if( ctx->state == waiting ) ctx->state = running; if( ctx->time == NULL ) ctx->time = g_timer_new(); else g_timer_continue(ctx->time); while( ctx->state == running ) { if( (ctx->steps % (1024*1024)) == 0 ) { g_debug("steps %li", ctx->steps); if( ctx->steps > conf->limits.steps ) { g_info("shellcode took too many steps ... (%li steps)", ctx->steps); ctx->state = failed; break; } if( conf->limits.cpu > 0. ) { double elapsed = g_timer_elapsed(ctx->time, NULL); if( elapsed > conf->limits.cpu ) { g_info("shellcode took too long ... (%f seconds)", elapsed); ctx->state = failed; break; } } } ctx->steps++; struct emu_env_hook *hook = NULL; hook = emu_env_w32_eip_check(env); if( hook != NULL ) { if( hook->hook.win->fnhook == NULL ) { g_critical("unhooked call to %s", hook->hook.win->fnname); break; } else if( ctx->state == waiting ) /* for now, we stop! * had a blocking io call * callback from main will come at a given point * and requeue us to the threadpool */ goto unlock_and_return; } else { ret = emu_cpu_parse(emu_cpu_get(e)); struct emu_env_hook *hook =NULL; if( ret != -1 ) { hook = emu_env_linux_syscall_check(env); if( hook == NULL ) { ret = emu_cpu_step(emu_cpu_get(e)); } else { if( hook->hook.lin->fnhook != NULL ) { hook->hook.lin->fnhook(env, hook); if( ctx->state == waiting ) /* stop * as mentioned previously */ goto unlock_and_return; } } } if( ret == -1 ) { g_debug("cpu error %s", emu_strerror(e)); break; } } } g_timer_stop(ctx->time); if( ctx->state == failed ) g_debug("emulating shellcode failed"); g_mutex_unlock(&ctx->mutex); #ifdef DEBUG double elapsed = g_timer_elapsed(ctx->time, NULL); g_debug("shellcode took %f seconds on cpu, %li steps", elapsed, ctx->steps); #endif GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds); g_async_queue_push(aq, async_cmd_new(emulate_ctx_free, ctx)); g_async_queue_unref(aq); ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger); return; unlock_and_return: g_timer_stop(ctx->time); g_mutex_unlock(&ctx->mutex); }
/*! \brief signal_read_rtvars_thread() is thread which fires off the read msg to get a new set of realtiem variables. It does so by queing messages to a thread which handles I/O. This function will check the queue depth and if the queue is backed up it will skip sending a request for data, as that will only aggravate the queue roadblock. \returns 0 on signal to exit */ G_MODULE_EXPORT void * signal_read_rtvars_thread(gpointer data) { static void (*signal_read_rtvars)(void); static gboolean (*setup_rtv)(void); static gboolean (*teardown_rtv)(void); Serial_Params *serial_params; GMutex * mutex = g_mutex_new(); GTimeVal time; GAsyncQueue *io_data_queue = NULL; GAsyncQueue *pf_dispatch_queue = NULL; GCond *rtv_thread_cond = NULL; GMutex *rtv_thread_mutex = NULL; serial_params = DATA_GET(global_data,"serial_params"); io_data_queue = DATA_GET(global_data,"io_data_queue"); pf_dispatch_queue = DATA_GET(global_data,"pf_dispatch_queue"); rtv_thread_cond = DATA_GET(global_data,"rtv_thread_cond"); rtv_thread_mutex = DATA_GET(global_data,"rtv_thread_mutex"); get_symbol("signal_read_rtvars",(void *)&signal_read_rtvars); get_symbol("setup_rtv",(void *)&setup_rtv); get_symbol("teardown_rtv",(void *)&teardown_rtv); g_return_val_if_fail(serial_params,NULL); g_return_val_if_fail(signal_read_rtvars,NULL); g_return_val_if_fail(io_data_queue,NULL); g_return_val_if_fail(pf_dispatch_queue,NULL); g_return_val_if_fail(rtv_thread_cond,NULL); g_return_val_if_fail(rtv_thread_mutex,NULL); if (setup_rtv) if (!setup_rtv()) g_thread_exit(NULL); g_mutex_lock(mutex); g_async_queue_ref(io_data_queue); g_async_queue_ref(pf_dispatch_queue); g_mutex_lock(rtv_thread_mutex); while (TRUE) { dbg_func(IO_MSG|THREADS,g_strdup(__FILE__": signal_read_rtvars_thread()\n\tsending message to thread to read RT vars\n")); signal_read_rtvars(); /* Auto-throttling if gui gets sluggish */ while (( g_async_queue_length(io_data_queue) > 2) || (g_async_queue_length(pf_dispatch_queue) > 3)) { g_get_current_time(&time); g_time_val_add(&time,1000*g_async_queue_length(pf_dispatch_queue)); if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time)) goto breakout; } g_get_current_time(&time); g_time_val_add(&time,serial_params->read_wait*1000); if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time)) goto breakout; } breakout: g_mutex_unlock(rtv_thread_mutex); g_async_queue_unref(io_data_queue); g_async_queue_unref(pf_dispatch_queue); g_mutex_unlock(mutex); g_mutex_free(mutex); if (teardown_rtv) teardown_rtv(); g_thread_exit(0); return NULL; }
void checkcopy_worker (CheckcopyWorkerParams * params) { GQueue *int_q; ProgressDialog * progress_dialog; CheckcopyPlanner *planner; CheckcopyProcessor *proc; CheckcopyFileList * list; gboolean verify_only; verify_only = g_file_has_uri_scheme (params->dest, "verify"); list = checkcopy_file_list_get_instance (); g_object_set (G_OBJECT (list), "verify-only", verify_only, NULL); progress_dialog = params->progress_dialog; planner = checkcopy_planner_new (progress_dialog); proc = checkcopy_processor_new (progress_dialog, params->dest, verify_only); int_q = g_queue_new (); ext_q = params->queue; g_async_queue_ref (ext_q); while (TRUE) { GFile *file; /* Collect everything from the external queue to calculate the size. * Since the files are not processed yet, stick them into the internal queue. * * At this point the internal queue is empty, so we can block once for getting the first item * from the external queue */ file = g_async_queue_pop (ext_q); progress_dialog_thread_set_status (progress_dialog, PROGRESS_DIALOG_STATUS_CALCULATING_SIZE); do { g_queue_push_tail (int_q, file); checkcopy_traverse (file, CHECKCOPY_FILE_HANDLER (planner)); } while ((file = g_async_queue_try_pop (ext_q)) != NULL); #ifdef DEBUG { gchar *size_str; guint64 total_size = 0; g_object_get (planner, "total-size", &total_size, NULL); size_str = g_format_size_for_display (total_size); DBG ("Total size is now %s", size_str); g_free (size_str); } #endif progress_dialog_thread_set_status (progress_dialog, PROGRESS_DIALOG_STATUS_COPYING); g_object_set (G_OBJECT (progress_dialog), "num-files", checkcopy_planner_get_num_files (planner), NULL); /* Now process the internal queue */ while ((file = g_queue_pop_head (int_q)) != NULL) { checkcopy_traverse (file, CHECKCOPY_FILE_HANDLER (proc)); g_object_unref (file); } checkcopy_file_list_write_checksum (list, params->dest); checkcopy_file_list_sweep (list); progress_dialog_thread_set_status (progress_dialog, PROGRESS_DIALOG_STATUS_COMPLETED); #ifdef DEBUG progress_dialog_thread_check_stats (progress_dialog); #endif DBG ("Waiting for more things to do"); } /* we won't ever get here but just in case * we change the loop condition later */ g_async_queue_unref (ext_q); g_queue_foreach (int_q, (GFunc) g_object_unref, NULL); g_queue_free (int_q); g_object_unref (planner); g_object_unref (proc); g_object_unref (list); g_object_unref (params->dest); g_free (params); }