void DLVEvaluator::solve(std::size_t ctx_id, Heads* heads, BeliefTablePtr btab, NewConcurrentMessageDispatcherPtr md) { reset_process(ctx_id, heads, btab); std::size_t k1 = heads->getK1(); std::size_t k2 = heads->getK2(); DBGLOG(DBG, "DLVEvaluator::solve(). k1 = " << k1 << ", k2 = " << k2); if (k1 == 0 && k2 == 0) { read_all(ctx_id, heads, btab, md); } else { assert (k1 <= k2); read_until_k2(ctx_id, k1, k2, heads, btab, md); } delete proc; proc = 0; // Either no more answer wrt this heads, // or k2 answers reached. // Send a NULL to EVAL_OUT int timeout = 0; HeadsBeliefStatePair* null_ans = new HeadsBeliefStatePair(); null_ans->first = heads; null_ans->second = NULL; md->send(NewConcurrentMessageDispatcher::EVAL_OUT_MQ, out_queue, null_ans, timeout); }
void cleanup ( struct process *process ) { int s; if ( process->sock != NO_SOCK ) { s = close ( process->sock ); current_total_processes--; if ( s == NO_SOCK ) { perror ( "close sock" ); } } if ( process->fd != -1 ) { s = close ( process->fd ); if ( s == NO_FILE ) { printf ( "fd: %d\n",process->fd ); printf ( "\n" ); perror ( "close file" ); } } process->sock = NO_SOCK; reset_process ( process ); }
void read_request ( struct process* process ) { int sock = process->sock, s; char* buf=process->buf; char read_complete = 0; ssize_t count; while ( 1 ) { count = read ( sock, buf + process->read_pos, BUF_SIZE - process->read_pos ); if ( count == -1 ) { if ( errno != EAGAIN ) { handle_error ( process, "read request" ); return; } else { //errno == EAGAIN表示读取完毕 break; } } else if ( count == 0 ) { // 被客户端关闭连接 cleanup ( process ); return; } else if ( count > 0 ) { process->read_pos += count; } } int header_length = process->read_pos; // determine whether the request is complete if ( header_length > BUF_SIZE - 1 ) { process->response_code = 400; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_400 ); send_response_header ( process ); handle_error ( processes, "bad request" ); return; } buf[header_length]=0; read_complete = ( strstr ( buf, "\n\n" ) != 0 ) || ( strstr ( buf, "\r\n\r\n" ) != 0 ); int error = 0; if ( read_complete ) { //重置读取位置 reset_process ( process ); // get GET info if ( !strncmp ( buf, "GET", 3 ) == 0 ) { process->response_code = 400; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_400 ); send_response_header ( process ); handle_error ( processes, "bad request" ); return; } // get first line int n_loc = ( int ) strchr ( buf, '\n' ); int space_loc = ( int ) strchr ( buf + 4, ' ' ); if ( n_loc <= space_loc ) { process->response_code = 400; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_400 ); send_response_header ( process ); handle_error ( processes, "bad request" ); return; } char path[255]; int len = space_loc - ( int ) buf - 4; if ( len > MAX_URL_LENGTH ) { process->response_code = 400; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_400 ); send_response_header ( process ); handle_error ( processes, "bad request" ); return; } buf[header_length] = 0; strncpy ( path, buf+4, len ); path[len] = 0; struct stat filestat; char fullname[256]; char *prefix = doc_root; strcpy ( fullname, prefix ); strcpy ( fullname + strlen ( prefix ), path ); s = get_index_file ( fullname, &filestat); if ( s == -1 ) { process->response_code = 404; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_404 ); send_response_header ( process ); handle_error ( processes, "not found" ); return; } int fd = open ( fullname, O_RDONLY ); process->fd = fd; if ( fd<0 ) { process->response_code = 404; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_404 ); send_response_header ( process ); handle_error ( processes, "not found" ); return; } else { process->response_code = 200; } char tempstring[256]; //检查有无If-Modified-Since,返回304 char* c = strstr ( buf, HEADER_IF_MODIFIED_SINCE ); if(c!=0){ char* rn = strchr(c, '\r'); if(rn==0){ rn = strchr(c, '\n'); if(rn==0){ process->response_code = 400; process->status = STATUS_SEND_RESPONSE_HEADER; strcpy ( process->buf, header_400 ); send_response_header ( process ); handle_error ( processes, "bad request" ); return; } } int time_len = rn - c - sizeof(HEADER_IF_MODIFIED_SINCE) + 1; strncpy(tempstring, c + sizeof(HEADER_IF_MODIFIED_SINCE) - 1,time_len); tempstring[time_len]=0; { struct tm tm; time_t t; strptime(tempstring, RFC1123_DATE_FMT, &tm); tzset(); t=mktime(&tm); t-=timezone; gmtime_r(&t, &tm); if(t >= filestat.st_mtime){ process->response_code = 304; } } } //开始header process->buf[0] = 0; if(process->response_code == 304){ write_to_header ( header_304_start ); } else { write_to_header ( header_200_start ); } process->total_length = filestat.st_size; { //写入当前时间 struct tm *tm; time_t tmt; tmt = time ( NULL ); tm = gmtime ( &tmt ); strftime ( tempstring, sizeof ( tempstring ), RFC1123_DATE_FMT, tm ); write_to_header ( "Date: " ); write_to_header ( tempstring ); write_to_header ( "\r\n" ); //写入文件修改时间 tm = gmtime ( &filestat.st_mtime ); strftime ( tempstring, sizeof ( tempstring ), RFC1123_DATE_FMT, tm ); write_to_header ( "Last-modified: " ); write_to_header ( tempstring ); write_to_header ( "\r\n" ); if(process->response_code == 200){ //写入content长度 sprintf ( tempstring, "Content-Length: %ld\r\n", filestat.st_size ); write_to_header ( tempstring ); } } //结束header write_to_header ( header_end ); process->status = STATUS_SEND_RESPONSE_HEADER; //修改此sock的监听状态,改为监视写状态 event.data.fd = process->sock; event.events = EPOLLOUT | EPOLLET; s = epoll_ctl ( efd, EPOLL_CTL_MOD, process->sock, &event ); if ( s == -1 ) { perror ( "epoll_ctl" ); abort (); } //发送header send_response_header ( process ); } }
struct process* accept_sock ( int listen_sock ) { int s; // 在ET模式下必须循环accept到返回-1为止 while ( 1 ) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; if ( current_total_processes >= MAX_PORCESS ) { // 请求已满,accept之后直接挂断 infd = accept ( listen_sock, &in_addr, &in_len ); if ( infd == -1 ) { if ( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) ) { /* We have processed all incoming connections. */ break; } else { perror ( "accept" ); break; } } close ( infd ); return; } in_len = sizeof in_addr; infd = accept ( listen_sock, &in_addr, &in_len ); if ( infd == -1 ) { if ( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) ) { /* We have processed all incoming connections. */ break; } else { perror ( "accept" ); break; } } getnameinfo ( &in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV ); /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ s = setNonblocking ( infd ); if ( s == -1 ) abort (); int on = 1; setsockopt ( infd, SOL_TCP, TCP_CORK, &on, sizeof ( on ) ); //添加监视sock的读取状态 event.data.fd = infd; event.events = EPOLLIN | EPOLLET; s = epoll_ctl ( efd, EPOLL_CTL_ADD, infd, &event ); if ( s == -1 ) { perror ( "epoll_ctl" ); abort (); } struct process* process = find_empty_process_for_sock ( infd ); current_total_processes++; reset_process ( process ); process->sock = infd; process->fd = NO_FILE; process->status = STATUS_READ_REQUEST_HEADER; } }