Changeset 2a3214e in mainline
- Timestamp:
- 2011-10-26T16:50:52Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8218b6b
- Parents:
- 6e88fea
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r6e88fea r2a3214e 447 447 } 448 448 449 /** Timer fibril. 450 * 451 * @param arg Timer 452 */ 453 static int fibril_timer_func(void *arg) 454 { 455 fibril_timer_t *timer = (fibril_timer_t *) arg; 456 int rc; 457 458 fibril_mutex_lock(&timer->lock); 459 460 while (true) { 461 while (timer->state != fts_active && 462 timer->state != fts_cleanup) { 463 464 if (timer->state == fts_cleanup) 465 break; 466 467 fibril_condvar_wait(&timer->cv, &timer->lock); 468 } 469 470 if (timer->state == fts_cleanup) 471 break; 472 473 rc = fibril_condvar_wait_timeout(&timer->cv, &timer->lock, 474 timer->delay); 475 if (rc == ETIMEOUT) { 476 timer->fun(timer->arg); 477 timer->state = fts_fired; 478 } 479 } 480 481 fibril_mutex_unlock(&timer->lock); 482 return 0; 483 } 484 485 /** Create new timer. 486 * 487 * @return New timer on success, @c NULL if out of memory. 488 */ 489 fibril_timer_t *fibril_timer_create(void) 490 { 491 fid_t fid; 492 fibril_timer_t *timer; 493 494 timer = calloc(1, sizeof(fibril_timer_t)); 495 if (timer == NULL) 496 return NULL; 497 498 fid = fibril_create(fibril_timer_func, (void *) timer); 499 if (fid == 0) { 500 free(timer); 501 return NULL; 502 } 503 504 fibril_mutex_initialize(&timer->lock); 505 fibril_condvar_initialize(&timer->cv); 506 507 timer->fibril = fid; 508 timer->state = fts_not_set; 509 510 fibril_add_ready(fid); 511 512 return timer; 513 } 514 515 /** Destroy timer. 516 * 517 * @param timer Timer, must not be active or accessed by other threads. 518 */ 519 void fibril_timer_destroy(fibril_timer_t *timer) 520 { 521 fibril_mutex_lock(&timer->lock); 522 assert(timer->state != fts_active); 523 timer->state = fts_cleanup; 524 fibril_condvar_broadcast(&timer->cv); 525 fibril_mutex_unlock(&timer->lock); 526 } 527 528 /** Set timer. 529 * 530 * Set timer to execute a callback function after the specified 531 * interval. 532 * 533 * @param timer Timer 534 * @param delay Delay in microseconds 535 * @param fun Callback function 536 * @param arg Argument for @a fun 537 */ 538 void fibril_timer_set(fibril_timer_t *timer, suseconds_t delay, 539 fibril_timer_fun_t fun, void *arg) 540 { 541 fibril_mutex_lock(&timer->lock); 542 timer->state = fts_active; 543 timer->delay = delay; 544 timer->fun = fun; 545 timer->arg = arg; 546 fibril_condvar_broadcast(&timer->cv); 547 fibril_mutex_unlock(&timer->lock); 548 } 549 550 /** Clear timer. 551 * 552 * Clears (cancels) timer and returns last state of the timer. 553 * This can be one of: 554 * - fts_not_set If the timer has not been set or has been cleared 555 * - fts_active Timer was set but did not fire 556 * - fts_fired Timer fired 557 * 558 * @param timer Timer 559 * @return Last timer state 560 */ 561 fibril_timer_state_t fibril_timer_clear(fibril_timer_t *timer) 562 { 563 fibril_timer_state_t old_state; 564 565 fibril_mutex_lock(&timer->lock); 566 old_state = timer->state; 567 timer->state = fts_not_set; 568 569 timer->delay = 0; 570 timer->fun = NULL; 571 timer->arg = NULL; 572 fibril_condvar_broadcast(&timer->cv); 573 fibril_mutex_unlock(&timer->lock); 574 575 return old_state; 576 } 577 449 578 /** @} 450 579 */ -
uspace/lib/c/include/fibril_synch.h
r6e88fea r2a3214e 107 107 fibril_condvar_t name = FIBRIL_CONDVAR_INITIALIZER(name) 108 108 109 typedef void (*fibril_timer_fun_t)(void *); 110 111 typedef enum { 112 /** Timer has not been set or has been cleared */ 113 fts_not_set, 114 /** Timer was set but did not fire yet */ 115 fts_active, 116 /** Timer has fired and has not been cleared since */ 117 fts_fired, 118 /** Timer is being destroyed */ 119 fts_cleanup 120 } fibril_timer_state_t; 121 122 /** Fibril timer. 123 * 124 * When a timer is set it executes a callback function (in a separate 125 * fibril) after a specified time interval. The timer can be cleared 126 * (canceled) before that. From the return value of fibril_timer_clear() 127 * one can tell whether the timer fired or not. 128 */ 129 typedef struct { 130 fibril_mutex_t lock; 131 fibril_condvar_t cv; 132 fid_t fibril; 133 fibril_timer_state_t state; 134 135 suseconds_t delay; 136 fibril_timer_fun_t fun; 137 void *arg; 138 } fibril_timer_t; 139 109 140 extern void fibril_mutex_initialize(fibril_mutex_t *); 110 141 extern void fibril_mutex_lock(fibril_mutex_t *); … … 129 160 extern void fibril_condvar_broadcast(fibril_condvar_t *); 130 161 162 extern fibril_timer_t *fibril_timer_create(void); 163 extern void fibril_timer_destroy(fibril_timer_t *); 164 extern void fibril_timer_set(fibril_timer_t *, suseconds_t, fibril_timer_fun_t, 165 void *); 166 extern fibril_timer_state_t fibril_timer_clear(fibril_timer_t *); 167 131 168 #endif 132 169 -
uspace/srv/net/tl/tcp/conn.c
r6e88fea r2a3214e 45 45 #include "segment.h" 46 46 #include "seq_no.h" 47 #include "state.h" 47 48 #include "tcp_type.h" 48 49 #include "tqueue.h" … … 51 52 #define SND_BUF_SIZE 4096 52 53 54 #define MAX_SEGMENT_LIFETIME (15*1000*1000) //(2*60*1000*1000) 55 #define TIME_WAIT_TIMEOUT (2*MAX_SEGMENT_LIFETIME) 56 53 57 LIST_INITIALIZE(conn_list); 54 58 55 59 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg); 60 static void tcp_conn_tw_timer_set(tcp_conn_t *conn); 56 61 57 62 /** Create new segment structure. … … 63 68 tcp_conn_t *tcp_conn_new(tcp_sock_t *lsock, tcp_sock_t *fsock) 64 69 { 65 tcp_conn_t *conn ;70 tcp_conn_t *conn = NULL; 66 71 67 72 /* Allocate connection structure */ 68 73 conn = calloc(1, sizeof(tcp_conn_t)); 69 74 if (conn == NULL) 70 return NULL; 75 goto error; 76 77 conn->tw_timer = fibril_timer_create(); 78 if (conn->tw_timer == NULL) 79 goto error; 71 80 72 81 /* Allocate receive buffer */ … … 78 87 79 88 conn->rcv_buf = calloc(1, conn->rcv_buf_size); 80 if (conn->rcv_buf == NULL) { 81 free(conn); 82 return NULL; 83 } 89 if (conn->rcv_buf == NULL) 90 goto error; 84 91 85 92 /** Allocate send buffer */ … … 88 95 conn->snd_buf_fin = false; 89 96 conn->snd_buf = calloc(1, conn->snd_buf_size); 90 if (conn->snd_buf == NULL) { 91 free(conn); 92 return NULL; 93 } 97 if (conn->snd_buf == NULL) 98 goto error; 94 99 95 100 /* Set up receive window. */ … … 109 114 110 115 return conn; 116 117 error: 118 if (conn != NULL && conn->rcv_buf != NULL) 119 free(conn->rcv_buf); 120 if (conn != NULL && conn->snd_buf != NULL) 121 free(conn->snd_buf); 122 if (conn != NULL && conn->tw_timer != NULL) 123 fibril_timer_destroy(conn->tw_timer); 124 if (conn != NULL) 125 free(conn); 126 127 return NULL; 111 128 } 112 129 … … 803 820 log_msg(LVL_DEBUG, "FIN received -> Time-Wait"); 804 821 conn->cstate = st_time_wait; 805 /* XXX start time-wait timer */ 822 /* Start the Time-Wait timer */ 823 tcp_conn_tw_timer_set(conn); 806 824 break; 807 825 case st_close_wait: … … 811 829 break; 812 830 case st_time_wait: 813 /* XXX Restart the 2 MSL time-wait timeout */ 831 /* Restart the Time-Wait timer */ 832 tcp_conn_tw_timer_set(conn); 814 833 break; 815 834 } … … 912 931 } 913 932 933 /** Time-Wait timeout handler. 934 * 935 * @param arg Connection 936 */ 937 static void tw_timeout_func(void *arg) 938 { 939 tcp_conn_t *conn = (tcp_conn_t *) arg; 940 941 log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn); 942 log_msg(LVL_DEBUG, " TW Timeout -> Closed"); 943 944 tcp_conn_remove(conn); 945 conn->cstate = st_closed; 946 } 947 948 /** Start or restart the Time-Wait timeout. 949 * 950 * @param conn Connection 951 */ 952 void tcp_conn_tw_timer_set(tcp_conn_t *conn) 953 { 954 fibril_timer_set(conn->tw_timer, TIME_WAIT_TIMEOUT, tw_timeout_func, 955 (void *)conn); 956 } 957 914 958 /** Trim segment to the receive window. 915 959 * -
uspace/srv/net/tl/tcp/state.c
r6e88fea r2a3214e 209 209 } 210 210 211 /** Time-wait timeout */212 void tcp_to_time_wait(void)213 {214 log_msg(LVL_DEBUG, "tcp_to_time_wait()");215 }216 217 211 /** 218 212 * @} -
uspace/srv/net/tl/tcp/state.h
r6e88fea r2a3214e 59 59 extern void tcp_to_user(void); 60 60 extern void tcp_to_retransmit(void); 61 extern void tcp_to_time_wait(void);62 61 63 62 #endif -
uspace/srv/net/tl/tcp/tcp_type.h
r6e88fea r2a3214e 122 122 tcp_tqueue_t retransmit; 123 123 124 /** Time-Wait timeout timer */ 125 fibril_timer_t *tw_timer; 126 124 127 /** Receive buffer */ 125 128 uint8_t *rcv_buf;
Note:
See TracChangeset
for help on using the changeset viewer.