/*{{{ _quit -- really quit*/ int _quit() { register WINDOW *win; static int really_quit=0; if (really_quit++) { /* we're in bad shape */ perror("PANIC!! Error during _quit()!"); setreuid(getuid(),getuid()); abort(); } MOUSE_OFF(screen,mousex,mousey); sleep(1); /* let the key (if any) un-press before resetting the kbd */ set_kbd(0); /* fix up keyboard modes */ kbd_reset(); /* reset the keyboard */ reset_tty(0); /* fix up console tty modes */ #ifdef MOVIE end_log(); /* turn off logging */ #endif /* fix pttys */ if (geteuid() < 2) for(win=active;win != (WINDOW *) 0;win=W(next)) { if (W(pid)>1) killpg(W(pid),SIGHUP); chmod(W(tty),0666); chown(W(tty),0,0); } /* fix utmp file */ #ifdef WHO close(getdtablesize()-1); /* make sure there are enough fd's left */ for(win=active;win != (WINDOW *) 0;win=W(next)) if (W(tty)) rm_utmp(W(tty)); #endif CLEAR(screen,BIT_CLR); do_cmd( 'q' ); /* do the quiting command */ bit_destroy(screen); }
int main(int argc, char *argv[]) { BITMAP *bp; int i; #ifdef MOVIE log_start(fopen("lines.log","w")); #endif bp=bit_open(SCREEN_DEV); bit_blit(bp,0,0,BIT_WIDE(bp),BIT_HIGH(bp),BIT_CLR,(BITMAP*)0,0,0); srand(getpid()*time((time_t*)0)); for (i=0; i<1000; i++) bit_line(bp,rand()%BIT_WIDE(bp),rand()%BIT_HIGH(bp),rand()%BIT_WIDE(bp),rand()%BIT_HIGH(bp),BIT_SET); bit_destroy(bp); #ifdef MOVIE log_end(); #endif exit(0); }
int CS_put(struct content_obj * content) { content = content_copy(content); log_assert(g_log, content != NULL, "CS: failed to allocate content"); pthread_mutex_lock(&_cs.lock); struct CS_segment * segment = (struct CS_segment * ) hash_get(_cs.table, content_prefix(content->name)); pthread_mutex_unlock(&_cs.lock); int rv = 0; if (content_is_segmented(content->name)) { if (segment) { pthread_mutex_lock(&segment->lock); int seq_no = content_seq_no(content->name); if (seq_no >= segment->num_chunks) { segment->chunks = realloc(segment->chunks, sizeof(struct content_obj * ) * (seq_no + 1)); segment->num_chunks = seq_no + 1; segment->chunks[seq_no] = content; struct bitmap * larger = bit_create(segment->num_chunks); memcpy(larger->map, segment->valid->map, segment->valid->num_words); bit_destroy(segment->valid); segment->valid = larger; bit_set(larger, seq_no); } else { if (bit_test(segment->valid, seq_no)) { content_obj_destroy(segment->chunks[seq_no]); } segment->chunks[seq_no] = content; bit_set(segment->valid, seq_no); } pthread_mutex_unlock(&segment->lock); } else { rv = -1; } } else { if (!segment) { segment = malloc(sizeof(struct CS_segment)); /* this is a content matching a prefix */ char * key = malloc(strlen(content->name->full_name)); strcpy(key, content->name->full_name); segment->index_chunk = content; segment->chunks = NULL; segment->num_chunks = -1; segment->valid = bit_create(0); pthread_mutex_init(&segment->lock, NULL); pthread_mutex_lock(&_cs.lock); hash_put(_cs.table, key, (void * ) segment); pthread_mutex_unlock(&_cs.lock); } else { pthread_mutex_lock(&segment->lock); if (segment->index_chunk) { content_obj_destroy(segment->index_chunk); } segment->index_chunk = content; pthread_mutex_unlock(&segment->lock); } } return rv; }
/*{{{ main*/ int main(int argc, char *argv[]) { /*{{{ variables*/ enum { NOTHING, LOCAL, REMOTE } in=NOTHING; int c; int x,y; int mouse_x,mouse_y; int image_width,image_height; int image_xoffset=0,image_yoffset=0; int my_width,my_height; int err=0,usage=0; BITMAP *bp; FILE *input; static struct menu_entry menu[] = { { "quit","q" } }; char file[_POSIX_PATH_MAX]; /*}}} */ /*{{{ parse arguments*/ while ((c=getopt(argc,argv,"l:r:"))!=EOF) { switch (c) { /*{{{ l file*/ case 'l': { if ((input=fopen(optarg,"r"))==(FILE*)0) { fprintf(stderr,"%s: Can't open %s\r\n",argv[0],optarg); err=1; } else in=LOCAL; break; } /*}}} */ /*{{{ r file*/ case 'r': { char *cwd; in=REMOTE; if (*optarg!='/' && *optarg!='.') { if ((cwd=getcwd((char*)0,(size_t)0))!=(char*)0) { strcpy(file,cwd); strcat(file,"/"); strcat(file,optarg); } else { fprintf(stderr,"%s: Can't get current directory\r\n",argv[0]); err=1; } } else strcpy(file,optarg); break; } /*}}} */ /*{{{ default*/ default: { usage=1; break; } /*}}} */ } } if (err) exit(err); if (usage || optind!=argc) { fprintf(stderr,"Usage: mgrview [-l file | -r file]\n"); exit(1); } if (in==NOTHING) { in=LOCAL; input=stdin; } /*}}} */ /*{{{ setup*/ ckmgrterm(argv[0]); m_setup(M_MODEOK); signal(SIGINT,clean); signal(SIGTERM,clean); signal(SIGPIPE,clean); m_ttyset(); m_push(P_MENU|P_EVENT|P_FLAGS); m_setmode(M_ABS); m_setcursor(CS_INVIS); menu_load(1,1,menu); m_setevent(REDRAW, "R"); m_setevent(RESHAPE, "R"); m_setevent(BUTTON_1,"[%p]"); m_setevent(BUTTON_2,"m"); m_flush(); /*}}} */ if (in==LOCAL) { /*{{{ load bitmap to client space*/ if ((bp=bitmapread(input))==(BITMAP*)0) { fprintf(stderr,"%s: No MGR bitmap.\r\n",argv[0]); clean(1); } image_width=BIT_WIDE(bp); image_height=BIT_HIGH(bp); /*}}} */ /*{{{ transfer bitmap to server space*/ m_func(BIT_SRC); m_bitcreate(IMAGE_BITMAP,image_width,image_height); m_bitldto(image_width,image_height,0,0,IMAGE_BITMAP,bit_size(image_width,image_height,BIT_DEPTH(bp))); fwrite(BIT_DATA(bp),bit_size(image_width,image_height,BIT_DEPTH(bp)),1,m_termout); m_flush(); bit_destroy(bp); /*}}} */ } else if (in==REMOTE) { /*{{{ transfer bitmap from server fs to server space*/ m_bitfromfile(IMAGE_BITMAP,file); m_get(); if (sscanf(m_linebuf,"%d %d",&image_width,&image_height)<2) { fprintf(stderr,"%s: No MGR bitmap.\r\n",argv[0]); clean(1); } /*}}} */ } /*{{{ user interaction*/ get_size((int*)0,(int*)0,&my_width,&my_height); display(image_xoffset,image_yoffset,my_width,my_height,image_width,image_height); m_flush(); while ((c=getc(m_termin))!='q') switch (c) { /*{{{ m -- left button displays menu*/ case 'm': { m_selectmenu(1); m_flush(); break; } /*}}} */ /*{{{ [%d %d] -- right button*/ case '[': { fscanf(m_termin,"%d %d]",&mouse_x,&mouse_y); /*{{{ compute new x start*/ if (my_width>image_width) image_xoffset=0; else if (mouse_x<=0) image_xoffset=0; else if (mouse_x>=my_width) image_xoffset=my_width-image_width; else { /*{{{ move x start by difference from mouse and middle*/ image_xoffset=image_xoffset-(mouse_x-my_width/2); /*}}} */ /*{{{ check and corrent range of x start*/ if (image_xoffset<my_width-image_width) image_xoffset=my_width-image_width; else if (image_xoffset>0) image_xoffset=0; /*}}} */ } /*}}} */ /*{{{ compute new y start*/ if (my_height>image_height) image_yoffset=0; else if (mouse_y<=0) image_yoffset=0; else if (mouse_y>=my_height) image_yoffset=my_height-image_height; else { /*{{{ move y start by difference from mouse and middle*/ image_yoffset=image_yoffset-(mouse_y-my_height/2); /*}}} */ /*{{{ check and corrent range of y start*/ if (image_yoffset<my_height-image_height) image_yoffset=my_height-image_height; else if (image_yoffset>0) image_yoffset=0; /*}}} */ } /*}}} */ display(image_xoffset,image_yoffset,my_width,my_height,image_width,image_height); m_flush(); break; } /*}}} */ /*{{{ R -- redraw*/ case 'R': { get_size((int*)0,(int*)0,&my_width,&my_height); /*{{{ compute new x offset*/ if (my_width<image_width) { if (image_xoffset<my_width-image_width) image_xoffset=my_width-image_width; } else image_xoffset=0; /*}}} */ /*{{{ compute new y offset*/ if (my_height<image_height) { if (image_yoffset<my_height-image_height) image_yoffset=my_height-image_height; } else image_yoffset=0; /*}}} */ m_func(BIT_CLR); m_bitwrite(0,0,my_width,my_height); m_func(BIT_SRC); m_bitcopyto(image_xoffset,image_yoffset,image_width,image_height,0,0,WINDOW_BITMAP,IMAGE_BITMAP); m_flush(); break; } /*}}} */ } /*}}} */ /*{{{ exit*/ m_bitdestroy(IMAGE_BITMAP); get_colrow(&x,&y); m_move(0,y-1); clean(0); /* NOTREACHED */ return 255; /*}}} */ }
/*{{{ main*/ int main(int argc, char *argv[]) { /*{{{ variables*/ int x, login_y, password_y; char loginstr[9], passwordstr[9], ret; char ttystr[_POSIX_PATH_MAX]; char *background = (char *)0; char *fontname = (char *)0; /*}}} */ /*{{{ parse arguments*/ { int c; while ((c = getopt(argc, argv, "b:f:")) != EOF) switch (c) { case 'b': background = optarg; break; case 'f': fontname = optarg; break; } /*{{{ parse tty*/ { int tty; if (optind + 1 > argc) { fprintf(stderr, "Usage: %s tty\n", argv[0]); exit(1); } else { strcpy(ttystr, "/dev/"); strcat(ttystr, argv[optind++]); } close(0); close(1); close(2); setsid(); if ((tty = open(ttystr, O_RDWR)) != 0) { fprintf(stderr, "%s: Can't open controlling terminal on fd 0.\n", argv[0]); exit(1); } fchmod(tty, 0600); fchown(tty, getuid(), getgid()); open(argv[optind], O_RDWR); open(argv[optind], O_RDWR); } /*}}} */ } /*}}} */ /*{{{ get into grafics mode*/ signal(SIGTERM, quit); signal(SIGHUP, quit); set_tty(0); if ((screen = bit_open(SCREEN_DEV)) == (BITMAP *)0) { reset_tty(0); exit(EX_NOPERM); } bit_grafscreen(); /*}}} */ /*{{{ load font*/ if (fontname) { char fontpath[_POSIX_PATH_MAX]; if (*fontname == '/' || *fontname == '.') strcpy(fontpath, fontname); else { strcpy(fontpath, ICONDIR); strcat(fontpath, "/"); strcat(fontpath, fontname); } if ((font = open_font(fontname)) == (struct font *)0) font = open_font((char *)0); } else font = open_font((char *)0); /*}}} */ /*{{{ draw background*/ bit_blit(screen, 0, 0, screen->wide, screen->high, BIT_CLR, (BITMAP *)0, 0, 0); if (background) { BITMAP *bp; FILE *fp; char backgroundpath[_POSIX_PATH_MAX]; if (*background == '/' || *background == '.') strcpy(backgroundpath, background); else { strcpy(backgroundpath, ICONDIR); strcat(backgroundpath, "/"); strcat(backgroundpath, background); } if ((fp = fopen(backgroundpath, "r")) != (FILE *)0 && (bp = bitmapread(fp)) != (BITMAP *)0) { int x, y; for (x = 0; x < screen->wide; x += bp->wide) bit_blit( screen, x, 0, screen->wide - x < bp->wide ? screen->wide - x : bp->wide, bp->high, BIT_SRC, bp, 0, 0); for (y = 0; y < screen->high; y += bp->high) bit_blit( screen, 0, y, screen->wide, screen->high - y < bp->high ? screen->high - y : bp->high, BIT_SRC, screen, 0, 0); } } /*}}} */ /*{{{ draw hostname*/ { int bx, bw, by, bh; char hostname[_POSIX_PATH_MAX]; struct hostent *h; gethostname(hostname, sizeof(hostname)); if ((h = gethostbyname(hostname)) != (struct hostent *)0) strcpy(hostname, h->h_name); bw = font->head.wide * (strlen(hostname) + 2); bh = 2 * font->head.high; bx = (screen->wide - bw) / 2; by = screen->high / 6 - bh / 2; cutebox(bx, by, bw, bh); printstr(bx + font->head.wide, by + bh - font->head.high / 2, hostname); } /*}}} */ /*{{{ draw login box*/ { int bx, bw, by, bh; bx = (screen->wide - font->head.wide * 40) / 2; by = (screen->high - font->head.high * 8) / 2; bw = font->head.wide * 40; bh = font->head.high * 8; cutebox(bx, by, bw, bh); } /*}}} */ /*{{{ draw login box contents*/ x = (screen->wide - font->head.wide * 18) / 2; login_y = screen->high / 2 - font->head.wide / 6; password_y = screen->high / 2 + font->head.high / 6 + font->head.high; printstr(x, password_y, "Password: "******"Press ESC for terminal login"); /*}}} */ while (1) { /*{{{ get login and password or escape*/ printstr(x, login_y, "Login: "******"mgr", (char *)0 }; int i; sprintf(env_user, "USER=%s", pw->pw_name); sprintf(env_logname, "LOGNAME=%s", pw->pw_name); sprintf(env_home, "HOME=%s", pw->pw_dir); sprintf(env_shell, "SHELL=%s", pw->pw_shell == (char *)0 || pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell); sprintf(env_path, "PATH=%s", PATH); sprintf(env_mail, "MAIL=%s/%s", MAILDIR, pw->pw_name); if (chdir(pw->pw_dir) != 0) chdir("/"); if (ttyname(0)) { chown(ttyname(0), pw->pw_uid, pw->pw_gid); chmod(ttyname(0), 0600); } for (i = 1; i <= _NSIG; i++) signal(i, SIG_DFL); bit_destroy(screen); reset_tty(0); initgroups(pw->pw_name, pw->pw_gid); setgid(pw->pw_gid); setuid(pw->pw_uid); sprintf(mgrlogin, "%s/.mgrlogin", pw->pw_dir); execve(mgrlogin, login_argv, login_env); execve(MGR_BINARY, login_argv, login_env); exit(EX_OSFILE); } /*}}} */ else /*{{{ incorrect login*/ { printstr((screen->wide - font->head.wide * 16) / 2, login_y + 3 * font->head.high, "Login incorrect"); } /*}}} */ } /*}}} */ } }
/*{{{ quit*/ __attribute__((noreturn)) void quit(int sig) { bit_destroy(screen); reset_tty(0); exit(1); }
/*{{{ shape -- reshape a window to specified dimensions*/ int shape(int x, int y, int dx, int dy) { int sx, sy, w, h; WINDOW *win; if (dx > 0) { sx = x; w = dx; } else { sx = x + dx; w = -dx; } if (dy > 0) { sy = y; h = dy; } else { sy = y + dy; h = -dy; } if (sx < 0) sx = 0; if (sx + w >= BIT_WIDE(screen)) w = BIT_WIDE(screen) - sx; if (sy + h >= BIT_HIGH(screen)) h = BIT_HIGH(screen) - sy; if (w < 2 * ACTIVE(borderwid) + ACTIVE(font)->head.wide * MIN_X || h < 2 * ACTIVE(borderwid) + ACTIVE(font)->head.high * MIN_Y) return (-1); #ifdef MGR_ALIGN alignwin(screen, &sx, &w, ACTIVE(borderwid)); #endif /* remove current window position */ save_win(active); erase_win(ACTIVE(border)); clip_bad(active); /* invalidate clip lists */ /* redraw remaining windows */ repair(active); /* adjust window state */ ACTIVE(x0) = sx; ACTIVE(y0) = sy; bit_destroy(ACTIVE(window)); bit_destroy(ACTIVE(border)); ACTIVE(border) = bit_create(screen, sx, sy, w, h); ACTIVE(window) = bit_create(ACTIVE(border), ACTIVE(borderwid), ACTIVE(borderwid), w - ACTIVE(borderwid) * 2, h - ACTIVE(borderwid) * 2); for (win = ACTIVE(next); win != (WINDOW *)0; win = W(next)) { if (W(flags) & W_ACTIVE && intersect(active, win)) save_win(win); } CLEAR(ACTIVE(window), PUTOP(BIT_CLR, ACTIVE(style))); border(active, BORDER_THIN); bit_blit(ACTIVE(border), 0, 0, BIT_WIDE(ACTIVE(save)) - ACTIVE(borderwid), BIT_HIGH(ACTIVE(save)) - ACTIVE(borderwid), BIT_SRC, ACTIVE(save), 0, 0); /* make sure character cursor is in a good spot */ if (ACTIVE(x) > BIT_WIDE(ACTIVE(window))) { ACTIVE(x) = 0; ACTIVE(y) += ((int)(ACTIVE(font)->head.high)); } if (ACTIVE(y) > BIT_HIGH(ACTIVE(window))) { #ifdef WIERD ACTIVE(y) = BIT_HIGH(ACTIVE(window)); scroll(ACTIVE(window), 0, BIT_HIGH(ACTIVE(window)), ((int)(ACTIVE(font)->head.high)), SWAPCOLOR(ACTIVE(style))); bit_blit(ACTIVE(window), 0, BIT_HIGH(ACTIVE(window)) - ((int)(ACTIVE(font)->head.high)), BIT_WIDE(ACTIVE(save)), ((int)(ACTIVE(font)->head.high)), BIT_SRC, ACTIVE(save), ACTIVE(borderwid), BIT_HIGH(ACTIVE(save)) - ((int)(ACTIVE(font)->head.high)) - ACTIVE(borderwid)); #else ACTIVE(y) = BIT_HIGH(ACTIVE(window)) - ((int)(ACTIVE(font)->head.high)); #endif } bit_destroy(ACTIVE(save)); ACTIVE(save) = (BITMAP *)0; /* invalidate clip lists */ clip_bad(active); un_covered(); set_size(active); return (0); }
static int retrieve_segment(struct segment * seg) { char proc[256]; snprintf(proc, 256, "rsg%u", g_nodeId); prctl(PR_SET_NAME, proc, 0, 0, 0); int rv = -1; log_print(g_log, "retrieve_segment: trying to retrieve segment %s[%d - %d].", seg->name->full_name, 0, seg->num_chunks-1); pthread_mutex_lock(&g_lock); int retries = g_interest_attempts; int timeout_ms = g_timeout_ms; pthread_mutex_unlock(&g_lock); int ttl = MAX_TTL; if ((seg->opts->mode & CCNFDNB_USE_RETRIES) == CCNFDNB_USE_RETRIES) { retries = seg->opts->retries; } if ((seg->opts->mode & CCNFDNB_USE_TIMEOUT) == CCNFDNB_USE_TIMEOUT) { timeout_ms = seg->opts->timeout_ms; } if ((seg->opts->mode & CCNFDNB_USE_TTL) == CCNFDNB_USE_TTL) { ttl = seg->opts->ttl; } struct chunk chunk_window[MAX_INTEREST_PIPELINE]; PENTRY _pit_handles[MAX_INTEREST_PIPELINE]; int pit_to_chunk[PIT_SIZE]; memset(&pit_to_chunk, 0, sizeof(pit_to_chunk)); struct bitmap * window = bit_create(MAX_INTEREST_PIPELINE); struct bitmap * missing = bit_create(seg->num_chunks); char str[MAX_NAME_LENGTH], comp[MAX_NAME_LENGTH]; strncpy(str, seg->name->full_name, seg->name->len); int rtt_est = timeout_ms; int cwnd = 1; int ssthresh = DEFAULT_INTEREST_PIPELINE; int fullfilled = 0; int min_rtt_est = 10; int current_chunk = 0; cc_state state = SLOW_START; int tx; _segment_q_t seg_q; pthread_mutex_init(&seg_q.mutex, NULL); pthread_cond_init(&seg_q.cond, NULL); seg_q.rcv_window = 0; seg_q.max_window = &cwnd; seg_q.rcv_chunks = linked_list_init(NULL); seg_q.base = seg->name; ccnfdnl_reg_segment(&seg_q); int i; window->num_bits = cwnd; while (!bit_allSet(missing)) { tx = cwnd; window->num_bits = cwnd; log_debug(g_log, "state = %d, cwnd = %d, ssthresh = %d rtt_est = %d", state, cwnd, ssthresh, rtt_est); while (tx && (current_chunk < seg->num_chunks)) { snprintf(comp, MAX_NAME_LENGTH - seg->name->len, "/%d", current_chunk); strncpy(str + seg->name->len, comp, seg->name->len); i = bit_find(window); if (i < 0 || i >= MAX_INTEREST_PIPELINE) { /* we must still be waiting for data */ break; } chunk_window[i].intr.name = content_name_create(str); chunk_window[i].intr.ttl = ttl; chunk_window[i].seq_no = current_chunk; chunk_window[i].retries = retries; _pit_handles[i] = PIT_get_handle(chunk_window[i].intr.name); if (!_pit_handles[i]) { bit_clear(window, i); break; } pit_to_chunk[_pit_handles[i]->index] = i; pthread_mutex_unlock(_pit_handles[i]->mutex); struct content_obj * co = CS_get(chunk_window[i].intr.name); if (!co) { log_debug(g_log, "expressing new interest: %s", chunk_window[i].intr.name->full_name); ccnfdnb_fwd_interest(&chunk_window[i].intr); tx--; } else { log_debug(g_log, "retrieved %s from CS", co->name->full_name); PENTRY pe = PIT_exact_match(chunk_window[i].intr.name); *pe->obj = co; pthread_mutex_unlock(pe->mutex); pthread_mutex_lock(&seg_q.mutex); linked_list_append(seg_q.rcv_chunks, pe); seg_q.rcv_window++; pthread_mutex_unlock(&seg_q.mutex); } current_chunk++; } log_debug(g_log, "tx window full"); pthread_mutex_lock(&seg_q.mutex); if (seg_q.rcv_chunks->len == 0) { struct timespec wait; ts_fromnow(&wait); ts_addms(&wait, 2 * rtt_est); rv = pthread_cond_timedwait(&seg_q.cond, &seg_q.mutex, &wait); if ((rv == ETIMEDOUT) && !seg_q.rcv_chunks->len) { /* we timed out, we need to rtx */ rtt_est += rtt_est / 2; if (rtt_est > PIT_LIFETIME_MS) rtt_est = PIT_LIFETIME_MS / 2; } } else { int pit_ages = 0; int pits_fulfilled = 0; while (seg_q.rcv_chunks->len > 0) { PENTRY pe = linked_list_remove(seg_q.rcv_chunks, 0); log_assert(g_log, pe != NULL, "invalid pit entry"); pthread_mutex_lock(pe->mutex); log_debug(g_log, "pit entry %s fulfilled", (*pe->obj)->name->full_name); int chunk_id = pit_to_chunk[pe->index]; log_assert(g_log, chunk_id >= 0, "invalid chunk id"); if (chunk_window[chunk_id].seq_no == 0) { seg->obj->publisher = (*pe->obj)->publisher; seg->obj->timestamp = (*pe->obj)->timestamp; seg->chunk_size = (*pe->obj)->size; } int offset = chunk_window[chunk_id].seq_no * seg->chunk_size; memcpy(&seg->obj->data[offset], (*pe->obj)->data, (*pe->obj)->size); content_obj_destroy(*pe->obj); struct timespec now; ts_fromnow(&now); ts_addms(&now, PIT_LIFETIME_MS); pit_ages += PIT_age(pe); pits_fulfilled++; pit_to_chunk[pe->index] = -1; PIT_release(pe); free(_pit_handles[chunk_id]); _pit_handles[chunk_id] = NULL; bit_clear(window, chunk_id); bit_set(missing, chunk_window[chunk_id].seq_no); log_debug(g_log, "retrieved chunk %s", chunk_window[chunk_id].intr.name->full_name); content_name_delete(chunk_window[chunk_id].intr.name); chunk_window[chunk_id].intr.name = NULL; cwnd++; if (state == CONG_AVOID) fullfilled++; } rtt_est -= floor(pit_ages / pits_fulfilled); if (rtt_est < min_rtt_est) rtt_est = min_rtt_est; } pthread_mutex_unlock(&seg_q.mutex); for (i = 0; i < MAX_INTEREST_PIPELINE; i++) { if (bit_test(window, i)) { if (!_pit_handles[i]) { continue; } pthread_mutex_lock(_pit_handles[i]->mutex); if (PIT_age(_pit_handles[i]) > (2 * rtt_est)) { PIT_refresh(_pit_handles[i]); chunk_window[i].retries--; ccnfdnb_fwd_interest(&chunk_window[i].intr); log_debug(g_log, "rtx interest: %s (rtt = %d)", chunk_window[i].intr.name->full_name, rtt_est); ssthresh = cwnd / 2 + 1; cwnd = 1; state = SLOW_START; } pthread_mutex_unlock(_pit_handles[i]->mutex); } } if ((cwnd >= ssthresh) && (state == SLOW_START)) state = CONG_AVOID; if (state == SLOW_START) fullfilled = 0; if ((fullfilled == cwnd) && (state == CONG_AVOID)) { cwnd++; fullfilled = 0; } if (cwnd > MAX_INTEREST_PIPELINE) cwnd = MAX_INTEREST_PIPELINE; /*log_debug(g_log, "cwnd = %d, ssthresh = %d", cwnd, ssthresh);*/ } log_debug(g_log, "retrieve_segment: finished for %s[%d-%d]", seg->name->full_name, 0, seg->num_chunks-1); rv = 0; PIT_print(); ccnfdnl_unreg_segment(&seg_q); pthread_mutex_destroy(&seg_q.mutex); pthread_cond_destroy(&seg_q.cond); while (seg_q.rcv_chunks->len) { PENTRY pe = linked_list_remove(seg_q.rcv_chunks, 0); content_obj_destroy(*pe->obj); PIT_release(pe); } bit_destroy(window); bit_destroy(missing); return rv; }