void ReliableSession::expire_naks() { if (this->nak_requests_.empty()) return; // nothing to expire ACE_Time_Value deadline(ACE_OS::gettimeofday()); deadline -= this->link_->config()->nak_timeout_; NakRequestMap::iterator first(this->nak_requests_.begin()); NakRequestMap::iterator last(this->nak_requests_.upper_bound(deadline)); if (first == last) return; // nothing to expire // Skip unrecoverable datagrams to // re-establish a baseline to detect future reception gaps. SequenceNumber lastSeq; if (last == this->nak_requests_.end()) { lastSeq = this->nak_requests_.rbegin()->second; } else { lastSeq = last->second; } if (lastSeq > this->nak_sequence_.low ()) { ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) WARNING: ") ACE_TEXT("ReliableSession::expire_naks: ") ACE_TEXT("timed out waiting on remote peer %d to send missing samples: %d - %d!\n"), this->remote_peer_, this->nak_sequence_.low ().getValue(), lastSeq.getValue())); this->nak_sequence_.shift(lastSeq); } // Clear expired repair requests: this->nak_requests_.erase(first, last); }
void ReliableSession::expire_naks() { if (this->nak_requests_.empty()) return; // nothing to expire ACE_Time_Value deadline(ACE_OS::gettimeofday()); deadline -= this->link_->config()->nak_timeout_; NakRequestMap::iterator first(this->nak_requests_.begin()); NakRequestMap::iterator last(this->nak_requests_.upper_bound(deadline)); if (first == last) return; // nothing to expire // Skip unrecoverable datagrams to // re-establish a baseline to detect future reception gaps. SequenceNumber lastSeq = (last == this->nak_requests_.end()) ? this->nak_requests_.rbegin()->second : last->second; std::vector<SequenceRange> dropped; if (this->nak_sequence_.insert(SequenceRange(this->nak_sequence_.low(), lastSeq), dropped)) { for (size_t i = 0; i < dropped.size(); ++i) { this->reassembly_.data_unavailable(dropped[i]); } ACE_ERROR((LM_WARNING, ACE_TEXT("(%P|%t) WARNING: ") ACE_TEXT("ReliableSession::expire_naks: ") ACE_TEXT("timed out waiting on remote peer %#08x%08x to send missing samples: %q - %q!\n"), (unsigned int)(this->remote_peer_ >> 32), (unsigned int) this->remote_peer_, this->nak_sequence_.low().getValue(), lastSeq.getValue())); } // Clear expired repair requests: this->nak_requests_.erase(first, last); deliver_held_data(); }
void Ask(const TRequest& request, TReply& reply) const { CNcbiOstream& job_in = m_Grid_cli->GetOStream(); // job input stream auto_ptr<CObjectOStream> outstr(TConnectTraits::GetOStream(job_in)); *outstr << request; if (job_in.bad()) { NCBI_THROW(CIOException, eWrite, "Error while writing request"); } outstr.reset(); m_Grid_cli->CloseStream(); CNetScheduleJob& job = m_Grid_cli->GetJob(); CDeadline deadline(m_Timeout, 0); CNetScheduleNotificationHandler submit_job_handler; submit_job_handler.SubmitJob(m_NS_api.GetSubmitter(), job, m_Timeout ); LOG_POST(Trace << "job: " << job.job_id); CNetScheduleAPI::EJobStatus status( submit_job_handler.WaitForJobCompletion(job, deadline, m_NS_api) ); // TODO The wait is over; the current job status is in the status // variable. CNetScheduleAPI::StatusToString(status) can convert it // to a human-readable string. if (status == CNetScheduleAPI::eDone) { // TODO The job has completed successfully. CStringOrBlobStorageReader reader(job.output, m_NC_api); CRStream rstr(&reader); auto_ptr<CObjectIStream> instr(TConnectTraits::GetIStream(rstr)); *instr >> reply; }
EIO_Status CConnTest::ExtraCheckOnFailure(void) { static const STimeout kTimeout = { 5, 0 }; static const STimeout kTimeSlice = { 0, 100000 }; static const struct { const char* host; const char* vhost; } kTests[] = { // 0. NCBI default { "", 0 }, // NCBI // 1. External server(s) { "www.google.com", 0 }, // NB: Google's public DNS (also @8.8.8.8), responds at :80 as well { "8.8.4.4", "www.google.com" }, // 2. NCBI servers, explicitly { "www.be-md.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI main { "www.st-va.ncbi.nlm.nih.gov", "www.ncbi.nlm.nih.gov" }, // NCBI colo { "130.14.29.110", "www.ncbi.nlm.nih.gov" }, // NCBI main { "165.112.7.20", "www.ncbi.nlm.nih.gov" } // NCBI colo }; m_CheckPoint.clear(); PreCheck(eNone, 0/*main*/, "Failback HTTP access check"); SConnNetInfo* net_info = ConnNetInfo_Create(0, eDebugPrintout_Data); if (!net_info) { PostCheck(eNone, 0/*main*/, eIO_Unknown, "Cannot create network info structure"); return eIO_Unknown; } net_info->req_method = eReqMethod_Head; net_info->timeout = &kTimeout; net_info->max_try = 0; m_Timeout = 0; CDeadline deadline(kTimeout.sec, kTimeout.usec * 1000); time_t sec; unsigned int nanosec; deadline.GetExpirationTime(&sec, &nanosec); ::sprintf(net_info->path, "/NcbiTest%08lX%08lX", (unsigned long) sec, (unsigned long) nanosec); vector< AutoPtr<CConn_HttpStream> > http; for (size_t n = 0; n < sizeof(kTests) / sizeof(kTests[0]); ++n) { char user_header[80]; _ASSERT(::strlen(kTests[n].host) < sizeof(net_info->host) - 1); if (kTests[n].host[0]) ::strcpy(net_info->host, kTests[n].host); if (kTests[n].vhost) { _ASSERT(::strlen(kTests[n].vhost) + 6 < sizeof(user_header) - 1); ::sprintf(user_header, "Host: %s", kTests[n].vhost); } else *user_header = '\0'; SAuxData* auxdata = new SAuxData(m_Canceled, 0); http.push_back(new CConn_HttpStream(net_info, user_header, s_AnyHeader, auxdata, s_Adjust, s_Cleanup)); http.back()->SetCanceledCallback(m_Canceled); } EIO_Status status = eIO_Success; do { if (!http.size()) break; ERASE_ITERATE(vector< AutoPtr<CConn_HttpStream> >, h, http) { CONN conn = (*h)->GetCONN(); if (!conn) { VECTOR_ERASE(h, http); if (status == eIO_Success) status = eIO_Unknown; continue; } EIO_Status readst = CONN_Wait(conn, eIO_Read, &kTimeSlice); if (readst > eIO_Timeout) { if (readst == eIO_Interrupt) { status = eIO_Interrupt; break; } if (status < readst && (*h)->GetStatusCode() != 404) status = readst; VECTOR_ERASE(h, http); continue; } } } while (status != eIO_Interrupt && !deadline.IsExpired()); if (status == eIO_Success && http.size()) status = eIO_Timeout; PostCheck(eNone, 0/*main*/, status, kEmptyStr); return status; }
int main(int argc, char **argv) { int fd_tcp, fd_ecp, newfd, clientlen, serverlen, ret, questionnaire_number, nbytes, nleft, size, score=0; struct sockaddr_in serveraddr, clientaddr; struct hostent *hostptr; unsigned short int TESport = TES_PORT, ECPport = ECP_PORT; ssize_t rcvd_bytes, send_bytes, read_file_bytes, send_bytes_data, AQT_bytes, AQS_bytes; char *SID, *QID, dtime[18+1], *data, filename[12+1], *correctanswers, *ptr1, ECPname[MAX_BUF], recv_str[MAX_BUF], send_str[MAX_BUF]; SID = (char*)malloc(sizeof(char) * (5 + 1)); QID = (char*)malloc(sizeof(char) * (23 + 1)); char usage[] = "usage: ./TES [-p TESport] [-n ECPname] [-e ECPport]"; time_t rawtime; struct tm * current_time; time (&rawtime); current_time = localtime (&rawtime); pid_t pid; void(*old_handler)(int);//interrupt handler /* Avoid zombies when child processes die. */ if ((old_handler = signal(SIGCHLD, SIG_IGN)) == SIG_ERR) exit(1); if (signal(SIGALRM, handler_alrm) == SIG_ERR) { perror("Error in signal"); exit(1); } if (argc % 2 != 1 || argc > 7) { printf("error: Incorrect number of arguments.\n%s\n", usage); return 1; } if (argc == 3) { if (!strcmp(argv[1], "-p")) TESport = atoi(argv[2]); else if (!strcmp(argv[1], "-n")) strcpy(ECPname, argv[2]); else if (!strcmp(argv[1], "-e")) ECPport = atoi(argv[2]); else { printf("error: Invalid option.\n%s\n", usage); return 1; } } if (argc == 5) { if (!strcmp(argv[1], "-p")) { TESport = atoi(argv[2]); if (!strcmp(argv[3], "-n")) strcpy(ECPname, argv[4]); else if (!strcmp(argv[3], "-e")) ECPport = atoi(argv[4]); else { printf("error: Invalid option.\n%s\n", usage); return 1; } } if (!strcmp(argv[1], "-n")) { strcpy(ECPname, argv[2]); if (!strcmp(argv[3], "-e")) ECPport = atoi(argv[4]); else { printf("error: Invalid option.\n%s\n", usage); return 1; } } else { printf("error: Invalid option.\n%s\n", usage); return 1; } } if (argc == 7) { if (!strcmp(argv[1], "-p")) { TESport = atoi(argv[2]); if (!strcmp(argv[3], "-n")) { strcpy(ECPname, argv[4]); if (!strcmp(argv[1], "-e")) ECPport = atoi(argv[2]); else { printf("error: Invalid option.\n%s\n", usage); return 1; } }else { printf("error: Invalid option.\n%s\n", usage); return 1; } }else { printf("error: Invalid option.\n%s\n", usage); return 1; } } if ((fd_tcp = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Error creating tcp socket.\n"); exit(1); } if ((fd_ecp = socket(AF_INET, SOCK_DGRAM, 0)) == -1){ perror("Error creating ecp socket.\n"); exit(1); } memset((void*)&serveraddr, (int)'\0', sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons((u_short)TESport); if (bind(fd_tcp, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1) { perror("Error: bind().\n"); exit(1); } if (listen(fd_tcp, 5) == -1){ perror("Error: listen().\n"); exit(1); } while (1) { clientlen = sizeof(clientaddr); do newfd = accept(fd_tcp, (struct sockaddr*)&clientaddr, &clientlen);//wait for a connection while (newfd == -1 && errno == EINTR); if (newfd == -1){ perror("Error: accept().\n"); exit(1); } /* Create a child process for each new connection. */ if ((pid = fork()) == -1) { perror("Error: fork().\n"); exit(1); } else if (pid == 0) { //child process close(fd_tcp); printf("Sent by [%s :%hu]\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port)); /* USER-TES Protocol (in TCP) */ ptr1 = readTCPclient(newfd); printf("\nReceived message:«%s»\n", ptr1); //we can use parseString() from functions.c... char* arr[8]; char * ch; ch = strtok(strdup(ptr1), " "); int i = 0; while (ch != NULL) { arr[i] = ch; i++; ch = strtok(NULL, " "); } /* USER-TES: RQT SID TES-USER: AQT QID time size data */ if (strcmp(arr[0], "RQT") == 0 && atoi(arr[1]) < 100000 && atoi(arr[1]) > 9999) { strcpy(SID, arr[1]); questionnaire_number = rand() % (NUM_OF_FILES + 1);//choose randomly 1 of available questionnaires sprintf(filename, "T%dQF%d.pdf", TES_NUMBER, questionnaire_number); sprintf(dtime, "%s",timeformat(deadline(current_time))); //generate QID: TES_NUMBER+questionnaire_number+deadline sprintf(QID, "%d_%d_%s", TES_NUMBER, questionnaire_number, timeformat1(deadline(current_time))); FILE *handler = fopen(filename, "rb"); if (handler == NULL){ perror("Error: fopen().\n"); exit(1); } fseek(handler, 0, SEEK_END); size = ftell(handler); rewind(handler); //allocate a string that can hold it all data = (char*)malloc(sizeof(char) * (size + 1)); //read it all in one operation read_file_bytes = fread(data, sizeof(char), size, handler); if (size != read_file_bytes) { free(data); perror("Error: fread().\n"); exit(1); } //each message ends with the character '\n' AQT_bytes = sprintf(send_str, "AQT %s %s %d ", QID, dtime, size); ptr1 = send_str; /* write() may write a smaller number of bytes than solicited */ nleft = AQT_bytes + read_file_bytes; // '\0' is not transmitted while (nleft > 0) { if (nleft > read_file_bytes) { send_bytes = write(newfd, ptr1, AQT_bytes); if (send_bytes <= 0) { perror("Error: write().\n"); exit(1); } nleft -= send_bytes; ptr1 += send_bytes; } else { send_bytes_data = write(newfd, data, nleft); if (send_bytes_data <= 0) { perror("Error: data write().\n"); exit(1); } nleft -= send_bytes_data; data += send_bytes_data; } } send_bytes_data = write(newfd, "\n", 1); if (send_bytes_data <= 0) { perror("Error: data write().\n"); exit(1); } close (newfd); exit(0); } else if (strcmp(arr[0], "RQS") == 0 ) { if (atoi(arr[1]) > 99999 || atoi(arr[1]) < 10000 || sizeof(arr[2]) > 24){ if ((send_bytes = write(newfd, "-2\n", 4)) <= 0)exit(1); close(newfd); exit(1); } strcpy(SID, arr[1]); strcpy(QID, arr[2]); if (checkdeadline(arr[2],current_time) == -1){ if ((send_bytes = write(newfd, "-1\n", 4)) <= 0)exit(1); close(newfd); exit(1); } for (i = 0; i < 5; i++) { if (strcmp(arr[i + 3], "A") == 0 || strcmp(arr[i + 3], "B") == 0 || strcmp(arr[i + 3], "C") == 0 || strcmp(arr[i + 3], "D") == 0 || strcmp(arr[i + 3], "N") == 0)continue; else { printf("\n----->invalid answers\n"); if ((send_bytes = write(newfd, "ERR\n", ERR_SIZE)) <= 0)exit(1); } } FILE *a = fopen(giveanswersfilename(QID), "r"); if (a == NULL) { perror("Error: fopen().\n"); exit(1); } fseek(a, 0, SEEK_END); size = ftell(a); rewind(a); //allocate a string that can hold it all correctanswers = (char*)malloc(sizeof(char) * (size)); //read it all in one operation if (fread(correctanswers, sizeof(char), size, a) <= 0) { perror("Error: fread().\n"); exit(1); } for (i = 0; i < 5; i++) { if (*correctanswers == arr[i + 3][0]) { score += 20; correctanswers+=3; } } AQS_bytes = sprintf(send_str, "AQS %s %d\n", QID, score); ptr1 = send_str; nbytes = AQS_bytes; // '\0' is not transmitted /* write() may write a smaller number of bytes than solicited */ nleft = nbytes; while (nleft > 0) { send_bytes = write(newfd, ptr1, nleft); if (send_bytes <= 0) exit(1); //error nleft -= send_bytes; ptr1 += send_bytes; } printf("TEST AQS sent : «%s»", send_str); close(newfd); /* TES-ECP Protocol (in UDP) */ memset((void*)&serveraddr, (int)'\0', sizeof(serveraddr)); serveraddr.sin_family = AF_INET; if ((hostptr = gethostbyname(ECPname)) == NULL) exit(1); printf("%s", ECPname); serveraddr.sin_addr.s_addr = ((struct in_addr*)(hostptr->h_addr_list[0]))->s_addr; //ECP server IP address printf("%s", hostptr->h_name); serveraddr.sin_port = htons((u_short)ECPport); serverlen = sizeof(serveraddr); /* TES-ECP: IQR SID QID topic_name score ECP-TES: AWI QID */ sprintf(send_str, "IQR %s %s %s %d\n", SID, QID, TOPIC_NAME, score); printf("%s\n",send_str); send_bytes = sendto(fd_ecp, send_str, strlen(send_str), 0, (struct sockaddr*)&serveraddr, serverlen); if (send_bytes == -1)exit(1);//error alarm(10);//generates the SIGALRM signal when the specified time has expired rcvd_bytes = recvfrom(fd_ecp, recv_str, strlen(recv_str), 0, (struct sockaddr*)&clientaddr, &clientlen); if (rcvd_bytes == -1)exit(1);//error else alarm(0); //cancel currently active alarm char *array[8]; char *c = strtok(recv_str, " "); int j = 0; while (c != NULL) { array[j] = c; j++; c = strtok(NULL, " "); } if (strcmp(array[0], "AWI") == 0 && strcmp(array[1], QID) == 0) { close(fd_ecp); exit(0); } else { send_bytes = sendto(fd_ecp, "ERR\n", ERR_SIZE, 0, (struct sockaddr*)&serveraddr, serverlen); if (send_bytes == -1)exit(1);//error exit(1); } } else { printf("\n----->invalid answers\n"); send_bytes = write(newfd, "ERR\n", ERR_SIZE); if (send_bytes <= 0)exit(1); close(newfd); exit(1); } } //parent process do ret = close(newfd); while (ret == -1 && errno == EINTR); if (ret == -1)exit(1);//error } }
void logger::run() { utxx::signal_block block_signals(m_block_signals); if (m_on_before_run) m_on_before_run(); if (!m_ident.empty()) pthread_setname_np(pthread_self(), m_ident.c_str()); int event_val; do { event_val = m_event.value(); //wakeup_result rc = wakeup_result::TIMEDOUT; while (!m_abort && m_queue.empty()) { m_event.wait(&m_wait_timeout, &event_val); ASYNC_DEBUG_TRACE( (" %s LOGGER awakened (res=%s, val=%d, futex=%d), abort=%d, head=%s\n", timestamp::to_string().c_str(), to_string(rc).c_str(), event_val, m_event.value(), m_abort, m_queue.empty() ? "empty" : "data") ); } // When running with maximum priority, occasionally excessive use of // sched_yield may use to system slowdown, so this option is // configurable by m_sched_yield_us: if (m_queue.empty() && m_sched_yield_us >= 0) { time_val deadline(rel_time(0, m_sched_yield_us)); while (m_queue.empty()) { if (m_abort) goto DONE; if (now_utc() > deadline) break; sched_yield(); } } // Get all pending items from the queue for (auto* item = m_queue.pop_all(), *next=item; item; item = next) { next = item->next(); try { dolog_msg(item->data()); } catch ( std::exception const& e ) { // Unhandled error writing data to some destination // Print error report to stderr (can't do anything better -- // the error happened in the m_on_error callback!) const msg msg(LEVEL_INFO, "", std::string("Fatal exception in logger"), UTXX_LOG_SRCINFO); detail::basic_buffered_print<1024> buf; char pfx[256], sfx[256]; char* p = format_header(msg, pfx, pfx + sizeof(pfx)); char* q = format_footer(msg, sfx, sfx + sizeof(sfx)); auto ps = p - pfx; auto qs = q - sfx; buf.reserve(msg.m_fun.str.size() + ps + qs + 1); buf.sprint(pfx, ps); buf.print(msg.m_fun.str); buf.sprint(sfx, qs); std::cerr << buf.str() << std::endl; m_abort = true; // TODO: implement attempt to store transient messages to some // other medium // Free all pending messages while (item) { m_queue.free(item); item = next; next = item->next(); } goto DONE; } m_queue.free(item); item = next; } } while (!m_abort); DONE: if (!m_silent_finish) { const msg msg(LEVEL_INFO, "", std::string("Logger thread finished"), UTXX_LOG_SRCINFO); try { dolog_msg(msg); } catch (...) {} } if (m_on_after_run) m_on_after_run(); }