/** Resumes processing the <b>next</b> HTTP request message within this connection. * * This method may only be invoked when the current/old request has been fully processed, * and is though only be invoked from within the finish handler of \p HttpRequest. * * \see HttpRequest::finish() */ void HttpConnection::resume() { TRACE("resume() shouldKeepAlive:%d)", shouldKeepAlive()); TRACE("-- (status:%s, inputOffset:%ld, inputSize:%ld)", status_str(), inputOffset_, input_.size()); status_ = KeepAliveRead; request_->clear(); if (socket()->tcpCork()) socket()->setTcpCork(false); }
bool test(const int n) { const int index = n - 1; const auto start_t = std::chrono::high_resolution_clock::now(); const long result = solvers[index](); const auto end_t = std::chrono::high_resolution_clock::now(); const double elapsed_s = std::chrono::duration<double>(end_t - start_t).count(); const bool success = result == answers[index]; const char* msg = status_str(success); printf("%02d: %12ld ... %4s (%g s)\n", n, result, msg, elapsed_s); return success; }
int mxq_load_jobs_running_on_server(struct mx_mysql *mysql, struct mxq_job **jobs_result, struct mxq_daemon *daemon) { struct mxq_job *jobs_tmp = NULL; struct mx_mysql_bind param = {0}; int idx; int res; assert(daemon); assert(daemon->hostname); assert(daemon->daemon_name); assert(*daemon->hostname); assert(*daemon->daemon_name); char *query = "SELECT" JOB_FIELDS " FROM" " mxq_job" " WHERE job_status IN (" status_str(MXQ_JOB_STATUS_LOADED) "," status_str(MXQ_JOB_STATUS_RUNNING) ")" " AND host_hostname = ?" " AND server_id = ?"; res = mx_mysql_bind_init_param(¶m, 2); assert(res == 0); idx = 0; res = 0; res += mx_mysql_bind_var(¶m, idx++, string, &daemon->hostname); res += mx_mysql_bind_var(¶m, idx++, string, &daemon->daemon_name); assert(res == 0); res=do_jobs_statement(mysql, query, ¶m, &jobs_tmp); if (res >= 0) *jobs_result = jobs_tmp; return res; }
bool HttpConnection::onMessageEnd() { TRACE("onMessageEnd() %s (isHandlingRequest:%d)", status_str(), flags_ & IsHandlingRequest); // marks the request-content EOS, so that the application knows when the request body // has been fully passed to it. request_->onRequestContent(BufferRef()); // If we are currently procesing a request, then stop parsing at the end of this request. // The next request, if available, is being processed via resume() if (flags_ & IsHandlingRequest) return false; return true; //shouldKeepAlive(); }
/** * This method gets invoked when there is data in our HttpConnection ready to read. * * We assume, that we are in request-parsing state. */ bool HttpConnection::readSome() { TRACE("readSome()"); ref(); if (status() == KeepAliveRead) { TRACE("readSome: status was keep-alive-read. resetting to reading-request", request_->outputState_); status_ = ReadingRequest; } ssize_t rv = socket_->read(input_); if (rv < 0) { // error switch (errno) { case EINTR: case EAGAIN: #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif watchInput(worker_->server_.maxReadIdle()); break; default: //log(Severity::error, "Connection read error: %s", strerror(errno)); goto err; } } else if (rv == 0) { // EOF TRACE("readSome: (EOF)"); goto err; } else { TRACE("readSome: read %ld bytes, status:%s, ros:%d", rv, status_str(), request_->outputState_); process(); } unref(); return true; err: abort(); unref(); return false; }
void HttpConnection::timeout(Socket *) { TRACE(1, "timedout: status=%s", status_str()); switch (status()) { case Undefined: case ReadingRequest: case ProcessingRequest: // we do not want further out-timing requests on this conn: just close it. abort(HttpStatus::RequestTimeout); break; case SendingReply: case SendingReplyDone: abort(); break; case KeepAliveRead: close(); break; } }
/** * Frees up any resources and resets state of this connection. * * This method is invoked only after the connection has been closed and * this resource may now either be physically destructed or put into * a list of free connection objects for later use of newly incoming * connections (to avoid too many memory allocations). */ void HttpConnection::clear() { TRACE(1, "clear(): refCount: %zu, conn.status: %s, parser.state: %s", refCount_, status_str(), state_str()); //TRACE(1, "Stack Trace:\n%s", StackTrace().c_str()); HttpMessageProcessor::reset(); if (request_) { request_->clear(); } clearCustomData(); worker_->server_.onConnectionClose(this); delete socket_; socket_ = nullptr; requestCount_ = 0; inputOffset_ = 0; input_.clear(); }
static void dump(void) { struct timeval now; struct lk *lk; int i; gettimeofday(&now, NULL); for (i = 0; i < maxn; i++) { lk = get_lock(i); printf("x %2d lkid %08x gr %2d rq %2d wait_ast %d last op %s \t%s %us\n", i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, lk->wait_ast, op_str(lk->lastop), status_str(lk->last_status), lk->wait_ast ? (unsigned int)(now.tv_sec - lk->begin.tv_sec) : 0); } }
int mxq_load_job_from_group_assigned_to_daemon(struct mx_mysql *mysql, struct mxq_job **jobs_result, uint64_t group_id, struct mxq_daemon *daemon) { struct mxq_job *jobs_tmp = NULL; struct mx_mysql_bind param = {0}; int res; int idx; assert(mysql); assert(jobs_result); assert(!(*jobs_result)); assert(daemon); assert(daemon->daemon_id); char *query = "SELECT" JOB_FIELDS " FROM" " mxq_job" " WHERE job_status = " status_str(MXQ_JOB_STATUS_ASSIGNED) " AND group_id = ?" " AND daemon_id = ?" " LIMIT 1"; res = mx_mysql_bind_init_param(¶m, 2); assert(res == 0); idx = 0; res = 0; res += mx_mysql_bind_var(¶m, idx++, uint64, &group_id); res += mx_mysql_bind_var(¶m, idx++, uint32, &daemon->daemon_id); assert(res == 0); res = do_jobs_statement(mysql, query, ¶m, &jobs_tmp); if (res >= 0) *jobs_result = jobs_tmp; return res; }
static int s2145_do_cmd(struct shinkos2145_ctx *ctx, uint8_t *cmd, int cmdlen, int minlen, int *num) { int ret; struct s2145_status_hdr *resp = (struct s2145_status_hdr *) rdbuf; libusb_device_handle *dev = ctx->dev; uint8_t endp_up = ctx->endp_up; uint8_t endp_down = ctx->endp_down; if ((ret = send_data(dev, endp_down, cmd, cmdlen))) return (ret < 0) ? ret : -99; ret = read_data(dev, endp_up, rdbuf, READBACK_LEN, num); if (ret < 0) return ret; if (*num < minlen) { ERROR("Short read! (%d/%d))\n", *num, minlen); return -99; } if (resp->result != RESULT_SUCCESS) { INFO("Printer Status: %02x (%s)\n", resp->status, status_str(resp->status)); INFO(" Result: 0x%02x Error: 0x%02x (0x%02x/0x%02x = %s)\n", resp->result, resp->error, resp->printer_major, resp->printer_minor, error_codes(resp->printer_major, resp->printer_minor)); return -99; } return ret; }
void HttpConnection::timeout(Socket *) { TRACE("timedout: status=%s", status_str()); switch (status()) { case StartingUp: TRACE("timeout: BUG. we should have never reached here."); break; case ReadingRequest: // we do not want further out-timing requests on this conn: just close it. setShouldKeepAlive(false); request_->status = HttpError::RequestTimeout; status_ = SendingReply; request_->finish(); break; case KeepAliveRead: close(); break; case SendingReply: abort(); break; } }
static int shinkos2145_main_loop(void *vctx, int copies) { struct shinkos2145_ctx *ctx = vctx; int ret, num; uint8_t cmdbuf[CMDBUF_LEN]; uint8_t rdbuf2[READBACK_LEN]; int i, last_state = -1, state = S_IDLE; struct s2145_cmd_hdr *cmd = (struct s2145_cmd_hdr *) cmdbuf;; struct s2145_print_cmd *print = (struct s2145_print_cmd *) cmdbuf; struct s2145_status_resp *sts = (struct s2145_status_resp *) rdbuf; struct s2145_mediainfo_resp *media = (struct s2145_mediainfo_resp *) rdbuf; /* Send Media Query */ memset(cmdbuf, 0, CMDBUF_LEN); cmd->cmd = cpu_to_le16(S2145_CMD_MEDIAINFO); cmd->len = cpu_to_le16(0); if ((ret = s2145_do_cmd(ctx, cmdbuf, sizeof(*cmd), sizeof(*media), &num)) < 0) { ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd)); return CUPS_BACKEND_FAILED; } if (le16_to_cpu(media->hdr.payload_len) != (sizeof(struct s2145_mediainfo_resp) - sizeof(struct s2145_status_hdr))) return CUPS_BACKEND_FAILED; /* Validate print sizes */ for (i = 0; i < media->count ; i++) { /* Look for matching media */ if (le16_to_cpu(media->items[i].columns) == cpu_to_le16(le32_to_cpu(ctx->hdr.columns)) && le16_to_cpu(media->items[i].rows) == cpu_to_le16(le32_to_cpu(ctx->hdr.rows)) && media->items[i].print_type == le32_to_cpu(ctx->hdr.method)) break; } if (i == media->count) { ERROR("Incorrect media loaded for print!\n"); return CUPS_BACKEND_HOLD; } // XXX check copies against remaining media! top: if (state != last_state) { if (dyesub_debug) DEBUG("last_state %d new %d\n", last_state, state); } /* Send Status Query */ memset(cmdbuf, 0, CMDBUF_LEN); cmd->cmd = cpu_to_le16(S2145_CMD_STATUS); cmd->len = cpu_to_le16(0); if ((ret = s2145_do_cmd(ctx, cmdbuf, sizeof(*cmd), sizeof(struct s2145_status_hdr), &num)) < 0) { ERROR("Failed to execute %s command\n", cmd_names(cmd->cmd)); return CUPS_BACKEND_FAILED; } if (memcmp(rdbuf, rdbuf2, READBACK_LEN)) { memcpy(rdbuf2, rdbuf, READBACK_LEN); INFO("Printer Status: 0x%02x (%s)\n", sts->hdr.status, status_str(sts->hdr.status)); if (sts->hdr.result != RESULT_SUCCESS) goto printer_error; if (sts->hdr.error == ERROR_PRINTER) goto printer_error; } else if (state == last_state) { sleep(1); goto top; } last_state = state; fflush(stderr); switch (state) { case S_IDLE: INFO("Waiting for printer idle\n"); /* If either bank is free, continue */ if (sts->bank1_status == BANK_STATUS_FREE || sts->bank2_status == BANK_STATUS_FREE) state = S_PRINTER_READY_CMD; break; case S_PRINTER_READY_CMD: INFO("Initiating print job (internal id %d)\n", ctx->jobid); memset(cmdbuf, 0, CMDBUF_LEN); print->hdr.cmd = cpu_to_le16(S2145_CMD_PRINTJOB); print->hdr.len = cpu_to_le16(sizeof (*print) - sizeof(*cmd)); print->id = ctx->jobid; print->count = cpu_to_le16(copies); print->columns = cpu_to_le16(le32_to_cpu(ctx->hdr.columns)); print->rows = cpu_to_le16(le32_to_cpu(ctx->hdr.rows)); print->media = le32_to_cpu(ctx->hdr.media); print->mode = le32_to_cpu(ctx->hdr.mode); print->method = le32_to_cpu(ctx->hdr.method); if ((ret = s2145_do_cmd(ctx, cmdbuf, sizeof(*print), sizeof(struct s2145_status_hdr), &num)) < 0) { ERROR("Failed to execute %s command\n", cmd_names(print->hdr.cmd)); return ret; } if (sts->hdr.result != RESULT_SUCCESS) { if (sts->hdr.error == ERROR_BUFFER_FULL) { INFO("Printer Buffers full, retrying\n"); break; } else if ((sts->hdr.status & 0xf0) == 0x30 || sts->hdr.status == 0x21) { INFO("Printer busy (%s), retrying\n", status_str(sts->hdr.status)); break; } else if (sts->hdr.status != ERROR_NONE) goto printer_error; } INFO("Sending image data to printer\n"); if ((ret = send_data(ctx->dev, ctx->endp_down, ctx->databuf, ctx->datalen))) return CUPS_BACKEND_FAILED; INFO("Waiting for printer to acknowledge completion\n"); sleep(1); state = S_PRINTER_SENT_DATA; break; case S_PRINTER_SENT_DATA: if (fast_return) { INFO("Fast return mode enabled.\n"); state = S_FINISHED; } else if (sts->hdr.status == STATUS_READY || sts->hdr.status == STATUS_FINISHED) { state = S_FINISHED; } break; default: break; }; if (state != S_FINISHED) goto top; INFO("Print complete\n"); return CUPS_BACKEND_OK; printer_error: ERROR("Printer reported error: %#x (%s) status: %#x (%s) -> %#x.%#x (%s)\n", sts->hdr.error, error_str(sts->hdr.error), sts->hdr.status, status_str(sts->hdr.status), sts->hdr.printer_major, sts->hdr.printer_minor, error_codes(sts->hdr.printer_major, sts->hdr.printer_minor)); return CUPS_BACKEND_FAILED; }
/** processes a (partial) request from buffer's given \p offset of \p count bytes. */ bool HttpConnection::process() { TRACE("process: offset=%ld, size=%ld (before processing)", inputOffset_, input_.size()); while (state() != MESSAGE_BEGIN || status() == ReadingRequest || status() == KeepAliveRead) { BufferRef chunk(input_.ref(inputOffset_)); if (chunk.empty()) break; // ensure status is up-to-date, in case we came from keep-alive-read if (status_ == KeepAliveRead) { TRACE("process: status=keep-alive-read, resetting to reading-request"); status_ = ReadingRequest; if (request_->isFinished()) { TRACE("process: finalizing request"); request_->finalize(); } } TRACE("process: (size: %ld, isHandlingRequest:%d, state:%s status:%s", chunk.size(), (flags_ & IsHandlingRequest) != 0, state_str(), status_str()); //TRACE("%s", input_.ref(input_.size() - rv).str().c_str()); HttpMessageProcessor::process(chunk, &inputOffset_); TRACE("process: done process()ing; fd=%d, request=%p state:%s status:%s", socket_->handle(), request_, state_str(), status_str()); if (isAborted()) return false; if (state() == SYNTAX_ERROR) { if (!request_->isFinished()) { setShouldKeepAlive(false); request_->status = HttpError::BadRequest; request_->finish(); } return false; } } TRACE("process: offset=%ld, bs=%ld, state=%s (after processing) io.timer:%d", inputOffset_, input_.size(), state_str(), socket_->timerActive()); return true; }
int mxq_set_job_status_exited(struct mx_mysql *mysql, struct mxq_job *job) { int res; int idx; uint16_t newstatus; struct mx_mysql_bind param = {0}; assert(mysql); assert(job); assert(job->host_pid); if (WIFEXITED(job->stats_status)) { if (WEXITSTATUS(job->stats_status)) { newstatus = MXQ_JOB_STATUS_FAILED; } else { newstatus = MXQ_JOB_STATUS_FINISHED; } } else if(WIFSIGNALED(job->stats_status)) { newstatus = MXQ_JOB_STATUS_KILLED; } else { mx_log_err("Status change to status_exit called with unknown stats_status (%d). Aborting Status change.", job->stats_status); errno = EINVAL; return -1; } char *query = "UPDATE" " mxq_job" " SET" " stats_max_sumrss = ?," " stats_status = ?," " stats_utime_sec = ?," " stats_utime_usec = ?," " stats_stime_sec = ?," " stats_stime_usec = ?," " stats_real_sec = ?," " stats_real_usec = ?," " stats_maxrss = ?," " stats_minflt = ?," " stats_majflt = ?," " stats_nswap = ?," " stats_inblock = ?," " stats_oublock = ?," " stats_nvcsw = ?," " stats_nivcsw = ?," " job_status = ?," " date_end = NULL" " WHERE job_status IN (" status_str(MXQ_JOB_STATUS_LOADED) "," status_str(MXQ_JOB_STATUS_RUNNING) "," status_str(MXQ_JOB_STATUS_KILLING) ")" " AND job_id = ?" " AND daemon_id = ?" " AND host_pid = ?"; res = mx_mysql_bind_init_param(¶m, 20); assert(res == 0); idx = 0; res = 0; res += mx_mysql_bind_var(¶m, idx++, uint64, &(job->stats_max_sumrss)); res += mx_mysql_bind_var(¶m, idx++, int32, &(job->stats_status)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_utime.tv_sec)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_utime.tv_usec)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_stime.tv_sec)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_stime.tv_usec)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_realtime.tv_sec)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_realtime.tv_usec)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_maxrss)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_minflt)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_majflt)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_nswap)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_inblock)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_oublock)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_nvcsw)); res += mx_mysql_bind_var(¶m, idx++, int64, &(job->stats_rusage.ru_nivcsw)); res += mx_mysql_bind_var(¶m, idx++, uint16, &(newstatus)); res += mx_mysql_bind_var(¶m, idx++, uint64, &(job->job_id)); res += mx_mysql_bind_var(¶m, idx++, uint32, &(job->daemon_id)); res += mx_mysql_bind_var(¶m, idx++, uint32, &(job->host_pid)); assert(res == 0); res = mx_mysql_do_statement_noresult_retry_on_fail(mysql, query, ¶m); if (res < 0) { mx_log_err("mx_mysql_do_statement(): %m"); return res; } job->job_status = newstatus; return res; }
/** processes a (partial) request from buffer's given \p offset of \p count bytes. */ bool HttpConnection::process() { TRACE(2, "process: offset=%lu, size=%lu (before processing) %s, %s", inputOffset_, input_.size(), state_str(), status_str()); while (state() != MESSAGE_BEGIN || status() == ReadingRequest || status() == KeepAliveRead) { BufferRef chunk(input_.ref(inputOffset_)); if (chunk.empty()) break; // ensure status is up-to-date, in case we came from keep-alive-read if (status_ == KeepAliveRead) { TRACE(1, "process: status=keep-alive-read, resetting to reading-request"); setStatus(ReadingRequest); if (request_->isFinished()) { TRACE(1, "process: finalizing request"); request_->finalize(); } } TRACE(1, "process: (size: %lu, isHandlingRequest:%d, state:%s status:%s", chunk.size(), isHandlingRequest(), state_str(), status_str()); //TRACE(1, "%s", input_.ref(input_.size() - rv).str().c_str()); size_t rv = HttpMessageProcessor::process(chunk, &inputOffset_); TRACE(1, "process: done process()ing; fd=%d, request=%p state:%s status:%s, rv:%d", socket_->handle(), request_, state_str(), status_str(), rv); if (isAborted()) { TRACE(1, "abort detected"); return false; } if (state() == SYNTAX_ERROR) { TRACE(1, "syntax error detected"); if (!request_->isFinished()) { abort(HttpStatus::BadRequest); } TRACE(1, "syntax error detected: leaving process()"); return false; } if (rv < chunk.size()) { request_->log(Severity::debug1, "parser aborted early."); return false; } } TRACE(1, "process: offset=%lu, bs=%lu, state=%s (after processing) io.timer:%d", inputOffset_, input_.size(), state_str(), socket_->timerActive()); return true; }
static void astfn(void *arg) { struct lk *lk = arg; int i = lk->id; if (!lk->wait_ast) { printf(" ast: %s %3d\t%x: !wait_ast gr %d rq %d last op %s %s\n", status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, op_str(lk->lastop), status_str(lk->last_status)); } log_ast(" ast: %s %3d\t%x\n", status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid); lk->last_status = lk->lksb.sb_status; if (lk->lksb.sb_status == EUNLOCK) { sts_eunlock++; memset(&lk->lksb, 0, sizeof(struct dlm_lksb)); lk->grmode = -1; lk->wait_ast = 0; } else if (lk->lksb.sb_status == ECANCEL) { sts_ecancel++; if (lk->grmode == -1) { memset(&lk->lksb, 0, sizeof(struct dlm_lksb)); lk->wait_ast = 0; } else { if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf) lk->wait_ast = 0; } } else if (lk->lksb.sb_status == ETIMEDOUT) { sts_etimedout++; if (lk->grmode == -1) { memset(&lk->lksb, 0, sizeof(struct dlm_lksb)); lk->wait_ast = 0; } else { if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf) lk->wait_ast = 0; } } else if (lk->lksb.sb_status == EDEADLK) { sts_edeadlk++; if (lk->grmode == -1) { memset(&lk->lksb, 0, sizeof(struct dlm_lksb)); lk->wait_ast = 0; } else { if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf) lk->wait_ast = 0; } } else if (lk->lksb.sb_status == EAGAIN) { sts_eagain++; if (lk->grmode == -1) { memset(&lk->lksb, 0, sizeof(struct dlm_lksb)); lk->wait_ast = 0; } else { if (lk->lastop != Op_unlockf) lk->wait_ast = 0; } } else { if (lk->lksb.sb_status != 0) { sts_other++; printf("BAD ast: %d %3d\t%x: gr %d rq %d last op %s %s\n", lk->lksb.sb_status, i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, op_str(lk->lastop), status_str(lk->last_status)); stress_stop = 1; return; } sts_zero++; if (lk->lastop != Op_unlockf) lk->wait_ast = 0; lk->grmode = lk->rqmode; if (minhold) { gettimeofday(&lk->acquired, NULL); lk->minhold = minhold; } } lk->rqmode = -1; }