static ssize_t ssl_send(IOBuf *iob, char *buffer, int len) { int sent = 0; int total = 0; check(iob->use_ssl, "IOBuf not set up to use ssl"); if(!iob->handshake_performed) { int rcode = ssl_do_handshake(iob); check(rcode == 0, "SSL handshake failed: %d", rcode); } for(sent = 0; len > 0; buffer += sent, len -= sent, total += sent) { sent = ssl_write(&iob->ssl, (const unsigned char*) buffer, len); check(sent != -1, "Error sending SSL data."); check(sent <= len, "Buffer overflow. Too much data sent by ssl_write"); // make sure we don't hog the process trying to stream out if(sent < len) { taskyield(); } }; return total; error: return -1; }
void fdtask(void *v) { int i, ms; PollResult result; int rc = 0; FDTASK = taskself(); rc = PollResult_init(POLL, &result); check(rc == 0, "Failed to initialize the poll result."); tasksystem(); taskname("fdtask"); for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); ms = next_task_sleeptime(500); if(task_was_signaled()) { fdtask_shutdown(); task_clear_signal(); break; } else { rc = SuperPoll_poll(POLL, &result, ms); check(rc != -1, "SuperPoll failure, aborting."); for(i = 0; i < rc; i++) { taskready(result.hits[i].data); } wake_sleepers(); } } PollResult_clean(&result); FDTASK = NULL; return; error: taskexitall(1); }
void fdtask(void *v) { int i, ms; PollResult result; int rc = 0; rc = PollResult_init(POLL, &result); check(rc == 0, "Failed to initialize the poll result."); tasksystem(); taskname("fdtask"); for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); ms = next_task_sleeptime(500); if(SIGNALED) { for(i = 0; i < SuperPoll_active_hot(POLL); i++) { Task *target = (Task *)SuperPoll_data(POLL, i); if(target) taskready(target); SuperPoll_compact_down(POLL, i); } } else { rc = SuperPoll_poll(POLL, &result, ms); check(rc != -1, "SuperPoll failure, aborting."); for(i = 0; i < rc; i++) { taskready(result.hits[i].data); } } wake_sleepers(); } PollResult_clean(&result); taskexit(0); error: taskexitall(1); }
void taskmain(int argc, char **argv) { int i, n; if(argc != 4){ fprintf(stderr, "usage: httpload n server url\n"); taskexitall(1); } n = atoi(argv[1]); server = argv[2]; url = argv[3]; for(i=0; i<n; i++){ taskcreate(fetchtask, 0, STACK); while(taskyield() > 1) ; sleep(1); } }
void taskmain(int argc, char **argv) { int i, n; if (argc != 4) { fprintf(stderr, "usage: httpload n server url\n"); taskexitall(1); } n = atoi(argv[1]); server = argv[2]; url = argv[3]; for (i = 0; i < n; i++) { taskcreate(fetchtask, 0, STACK); // 创建协程, 设置为可以运行的状态 // 其实fetchtask不是上下文切换的第一个函数, taskstart才是, 后者立即调用fetchtask while (taskyield() > 1) // 主动释放CPU, 这里循环其实是为了给其他协程足够的机会 ; sleep(1); } }
static void taskmain(ltctx *lt, void *unused) { int i, n; if(argc != 4) { fprintf(stderr, "usage: httpload n server url\n"); fprintf(stderr, " ex: httpload 4 127.0.0.1 /\n"); taskexit(lt, 1); } n = atoi(argv[1]); server = argv[2]; url = argv[3]; for(i=0; i<n; i++) { taskcreate(lt, fetchtask, 0, STACK); while(taskyield(lt) > 1) ; //taskdelay(lt, 1/*ms*/); } }
void fdtask(void *v) { int i, ms; Task *t; uvlong now; tasksystem(); taskname("fdtask"); for(;;){ //fprintf(stderr,"pooling0\n"); /* let everyone else run */ taskyield(); //fprintf(stderr,"\n after yield %d\n", maysamYieldRet); //while(taskyield() > 0); /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); //Added by Maysam Yabandeh //taskname("fdtask(%d)",npollfd); if((t=sleeping.head) == nil) ms = -1; else{ /* sleep at most 5s */ now = nsec(); if(now >= t->alarmtime) ms = 0; else if(now+5*1000*1000*1000LL >= t->alarmtime) ms = (t->alarmtime - now)/1000000; else ms = 5000; } //Added by Maysam Yabandeh //if (ms == -1 && maysamYieldRet == 0) ms = 0; if (ms == -1) ms = 0; //fprintf(stderr,"pooling ms is %d npollfd is %d\n", ms, npollfd); #ifndef USE_SHM if(poll(pollfd, npollfd, ms) < 0){ //fprintf(stderr,"pooling error\n"); if(errno == EINTR) continue; fprint(2, "poll: %s\n", strerror(errno)); taskexitall(0); } //fprintf(stderr,"pooling2\n"); /* wake up the guys who deserve it */ for(i=0; i<npollfd; i++){ while(i < npollfd && pollfd[i].revents){ //fprintf(stderr,"pooling3\n"); taskready(polltask[i]); --npollfd; pollfd[i] = pollfd[npollfd]; polltask[i] = polltask[npollfd]; } } #else /* wake up the guys who deserve it */ //extern mpass::MessageEndPoint msg_end_point; mpass::MessageEndPoint *end_point = &mpass::msg_end_point; for(i=0; i<npollfd; i++){ int &fd = pollfd[i].fd; bool read = pollfd[i].events & POLLIN; mpass::Connection *conn = &end_point->conn_array[fd]; if ( (read && !conn->rcv_q->is_empty()) || (!read && !conn->snd_q->is_full()) ) { taskready(polltask[i]); --npollfd; pollfd[i] = pollfd[npollfd]; polltask[i] = polltask[npollfd]; } } #endif //fprintf(stderr,"pooling4\n"); now = nsec(); while((t=sleeping.head) && now >= t->alarmtime){ //fprintf(stderr,"pooling5\n"); deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } } }
void fdtask(void *v) { int i, ms; Task *t; uvlong now; tasksystem(); taskname("fdtask"); struct epoll_event events[20000]; for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - epoll for i/o */ errno = 0; taskstate("epoll"); if(sleeping.head == nil && blocking.head == nil) ms = -1; else{ /* sleep at most 100ms */ now = nsec(); if (t) { if(now >= t->alarmtime) ms = 0; else if(now+500*1000*1000LL >= t->alarmtime) ms = (t->alarmtime - now)/1000000; else ms = 500; }else{ ms = 500; } } int nevents; if((nevents = epoll_wait(epfd, events, 20000, ms)) < 0){ if(errno == EINTR) continue; fprint(2, "epoll: %s\n", strerror(errno)); taskexitall(0); } /* wake up the guys who deserve it */ for(i=0; i<nevents; i++){ //deleting it from blocking queue for (t = blocking.head; t!= nil && t!= events[i].data.ptr; t=t->next) ; if(t==events[i].data.ptr) deltask(&blocking,t); taskready((Task *)events[i].data.ptr); } now = nsec(); while((t=sleeping.head) && now >= t->alarmtime){ deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } /*wake up the guys who are blocked */ while((t=blocking.head) && now >= t->alarmtime){ deltask(&blocking, t); if(!t->system && --blockingcounted == 0) taskcount--; taskready(t); } } }
static inline void hardsleep(int sec) { taskyield(); sleep(sec); }