DPI_LINK_DECL DPI_DLLESPEC void get_request(request_type* req) { char msg[512]; int nbytes; int i; client_sock = poll_socket(msg, &nbytes); if (client_sock != -1) { int cmd; int rw; unsigned int data[4]; sscanf(msg, "%d", &cmd); debug(stderr, "cmd=%d msg=%s\n", cmd, msg); req->cmd = cmd; if (cmd == 1) { request = 1; debug(stderr, "(request) reset\n"); } else if (cmd == 2) { sscanf(msg, "%d %d %u %u %u %u %u", &cmd, &rw, &req->addr, &data[3], &data[2], &data[1], &data[0]); for (i=0; i<8; i++) { req->rw[i] = rw&0x1; rw = rw >> 1; } req->data[0] = data[0]&0xffff; req->data[1] = (data[0]>>16)&0xffff; req->data[2] = data[1]&0xffff; req->data[3] = (data[1]>>16)&0xffff; req->data[4] = data[2]&0xffff; req->data[5] = (data[2]>>16)&0xffff; req->data[6] = data[3]&0xffff; req->data[7] = (data[3]>>16)&0xffff; previous_rw = rw; previous_addr = req->addr; request = 2; debug(stderr, "(request) rw=%d, addr=%08x, data=%08x\n", req->rw[0], req->addr, req->data[0]); }
void XDebugServer::pollSocketLoop() { while (true) { // Take some load off the CPU when polling thread is paused. std::this_thread::sleep_for(std::chrono::seconds(1)); // XXX: This can take the lock even when we want to pause the thread. std::lock_guard<std::mutex> lock(m_pollingMtx); // We're paused if the request thread is handling commands right now. if (m_pausePollingThread.load()) { continue; } // We've been told to exit. if (m_stopPollingThread.load()) { log("Polling thread stopping\n"); break; } // At this point we know that the request thread is busy running, so we let // it enter the jit. m_requestThread->m_reqInjectionData.setDebuggerIntr(false); if (m_bufferAvail == 0) { // Check if there is any input waiting on us. if (!poll_socket(m_socket)) { continue; } // Actually get the input from the socket. if (!readInput()) { log("Polling thread had input but failed to read it\n"); continue; } } try { log("Polling thread received: %s\n", m_bufferCur); auto cmd = parseCommand(); if (cmd->getCommandStr() != "break") { delete cmd; continue; } log("Received break command\n"); // We're going to set the 'break' flag on our XDebugServer, and pause // ourselves. The request thread will unpause us when it exits its // command loop. m_pausePollingThread.store(true); auto const old = m_break.exchange(cmd); always_assert(old == nullptr); // Force request thread to run in the interpreter, and hit // XDebugHookHandler::onOpcode(). m_requestThread->m_reqInjectionData.setDebuggerIntr(true); m_requestThread->m_reqInjectionData.setFlag(DebuggerSignalFlag); } catch (const XDebugExn&) { log("Polling thread got invalid command: %s\n", m_bufferCur); // Can drop the error. } } }
static int poll_outgoing(const struct dbg_context* dbg, int timeoutMs) { return poll_socket(dbg, POLLOUT /* TODO: |POLLERR */, timeoutMs); }