void qlog_destroy_free_list() { qmutex_lock(&free_log_list_lock); qfreelist_destroy(&free_log_list); qmutex_unlock(&free_log_list_lock); qmutex_destroy(&free_log_list_lock); }
void disp_request_t::flush() { qmutex_lock(mtx); for (qvector<json_object*>::iterator i = objects.begin(); i != objects.end(); i++) { json_object_put(*i); } objects.clear(); qmutex_unlock(mtx); }
void qlog_free(qlist_t *free_list) { qmutex_lock(&free_log_list_lock); qlist_splice_tail(free_list, &(free_log_list.free)); qmutex_unlock(&free_log_list_lock); }
//queue up a received datagram for eventual handlng via IDA's execute_sync mechanism //call no sdk functions other than execute_sync void disp_request_t::queueObject(json_object *obj) { bool call_exec = false; qmutex_lock(mtx); objects.push_back(obj); call_exec = objects.size() == 1; qmutex_unlock(mtx); if (call_exec) { //only invoke execute_sync if the buffer just added was at the head of the queue //in theory this allows multiple datagrams to get queued for handling //in a single execute_sync callback execute_sync(*this, MFF_WRITE); } }
void handle_session(rpc_server_t *server) { #ifndef __SINGLE_THREADED_SERVER__ qthread_t t = qthread_create(thread_handle_session, (void *)server); // Add the session to the list qmutex_lock(g_lock); clients_list[server] = t; qmutex_unlock(g_lock); #else g_global_server = server; handle_single_session(server); g_global_server = NULL; #endif }
bool BufferList::enqueue(Buffer *b) { bool first = false; BufferNode *n = new BufferNode(b); qmutex_lock(mtx); if (tail) { tail->next = n; } else { head = n; first = true; } tail = n; qmutex_unlock(mtx); return first; }
Buffer *BufferList::dequeue() { Buffer *b = NULL; if (head) { BufferNode *bn = head; b = head->buf; qmutex_lock(mtx); head = head->next; if (head == NULL) { tail = NULL; } qmutex_unlock(mtx); delete bn; } return b; }
// perform an action (func) on all debuggers int for_all_debuggers(debmod_visitor_t &v) { int code = 0; qmutex_lock(g_lock); { rpc_server_list_t::iterator it; for ( it=clients_list.begin(); it != clients_list.end(); ++it ) { code = v.visit(it->first->get_debugger_instance()); if ( code != 0 ) break; } } qmutex_unlock(g_lock); return code; }
//-------------------------------------------------------------------------- static void NT_CDECL shutdown_gracefully(int signum) { qeprintf("got signal #%d\n", signum); #ifdef __SINGLE_THREADED_SERVER__ if ( g_global_server != NULL ) { debmod_t *d = g_global_server->get_debugger_instance(); if ( d != NULL ) d->dbg_exit_process(); g_global_server->term_irs(); } #else qmutex_lock(g_lock); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { rpc_server_t *server = it->first; qthread_t thr = it->second; // free thread if ( thr != NULL ) qthread_free(thr); if ( server == NULL || server->irs == NULL ) continue; debmod_t *d = server->get_debugger_instance(); if ( d != NULL ) d->dbg_exit_process(); // kill the process instead of letting it run in wild server->term_irs(); } clients_list.clear(); qmutex_unlock(g_lock); qmutex_free(g_lock); #endif if ( listen_socket != INVALID_SOCKET ) closesocket(listen_socket); term_subsystem(); _exit(1); }
qlog_t* qlog_new() { /* seems freelist no effect, so alloc directly */ return qcalloc(sizeof(qlog_t)); qlog_t *log; qmutex_lock(&free_log_list_lock); log = (qlog_t*)qfreelist_new(&free_log_list); qmutex_unlock(&free_log_list_lock); if (log != NULL) { /* del it from freelist alloc list */ qlist_del_init(&log->fentry); } return log; }
//this is the callback that gets called by execute_sync, in theory new datagrams //can arrive and be processed during the loop since queue synchronization takes //place within the StringList int idaapi disp_request_t::execute(void) { while (objects.size() > 0) { qmutex_lock(mtx); qvector<json_object*>::iterator i = objects.begin(); json_object *obj = *i; objects.erase(i); qmutex_unlock(mtx); bool res = (*_disp)(obj); if (!res) { //not sure we really care what is returned here // msg(PLUGIN_NAME": connection to server severed at dispatch.\n"); // comm->cleanup(true); //probably not the right thing to do?? // break; } else { //msg(PLUGIN_NAME": dispatch routine called successfully.\n"); } } return 0; }
//-------------------------------------------------------------------------- static void handle_single_session(rpc_server_t *server) { lprintf("=========================================================\n" "Accepting incoming connection...\n"); qstring open = prepare_rpc_packet(RPC_OPEN); append_long(open, IDD_INTERFACE_VERSION); append_long(open, DEBUGGER_ID); append_long(open, sizeof(ea_t)); rpc_packet_t *rp = server->process_request(open, PRF_LOGIN|PRF_DONT_POLL); if ( rp == NULL ) { lprintf("Could not establish the connection\n"); delete server; return; } // Answer is beyond the rpc_packet_t buffer const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; bool send_response = true; bool ok = extract_long(&answer, end); if ( !ok ) { lprintf("Incompatible IDA Pro version\n"); send_response = false; } else if ( server_password != NULL ) { char *pass = extract_str(&answer, end); if ( strcmp(pass, server_password) != '\0' ) { lprintf("Bad password\n"); ok = false; } } qfree(rp); if ( send_response ) { server->poll_debug_events = false; server->has_pending_event = false; open = prepare_rpc_packet(RPC_OK); append_long(open, ok); server->send_request(open); if ( ok ) { qstring cmd; rpc_packet_t *packet = server->process_request(cmd, PRF_POLL); if ( packet != NULL ) qfree(packet); } } server->network_error_code = 0; lprintf("Closing incoming connection...\n"); server->term_irs(); #ifndef __SINGLE_THREADED_SERVER__ // Remove the session from the list qmutex_lock(g_lock); for (rpc_server_list_t::iterator it = clients_list.begin(); it != clients_list.end();++it) { if ( it->first != server ) continue; // free the thread resources qthread_free(it->second); // remove client from the list clients_list.erase(it); break; } qmutex_unlock(g_lock); #endif // Free the debug session delete server; }
//-------------------------------------------------------------------------- bool srv_lock_end(void) { return qmutex_unlock(g_lock); }
//-------------------------------------------------------------------------- bool lock_end(void) { return qmutex_unlock(g_mutex); }