Changeset 1369:f1bbcab403a6 in freeDiameter
- Timestamp:
- Jun 10, 2019, 11:27:54 PM (5 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdproto/sessions.c
r1093 r1369 35 35 36 36 /* Sessions module. 37 * 37 * 38 38 * Basic functionalities to help implementing User sessions state machines from RFC3588. 39 39 */ … … 92 92 struct session { 93 93 int eyec; /* Eyecatcher, SI_EYEC */ 94 94 95 95 os0_t sid; /* The \0-terminated Session-Id */ 96 96 size_t sidlen; /* cached length of sid */ 97 97 uint32_t hash; /* computed hash of sid */ 98 98 struct fd_list chain_h;/* chaining in the hash table of sessions. */ 99 99 100 100 struct timespec timeout;/* Timeout date for the session */ 101 101 struct fd_list expire; /* List of expiring sessions, ordered by timeouts. */ 102 102 103 103 pthread_mutex_t stlock; /* A lock to protect the list of states associated with this session */ 104 104 struct fd_list states; /* Sentinel for the list of states of this session. */ … … 126 126 static struct fd_list exp_sentinel = FD_LIST_INITIALIZER(exp_sentinel); /* list of sessions ordered by their timeout date */ 127 127 static pthread_mutex_t exp_lock = PTHREAD_MUTEX_INITIALIZER; /* lock protecting the list. */ 128 static pthread_cond_t exp_cond = PTHREAD_COND_INITIALIZER; /* condvar used by the expiry mec ahinsm. */128 static pthread_cond_t exp_cond = PTHREAD_COND_INITIALIZER; /* condvar used by the expiry mechainsm. */ 129 129 static pthread_t exp_thr = (pthread_t)NULL; /* The expiry thread that handles cleanup of expired sessions */ 130 130 … … 141 141 { 142 142 struct session * sess; 143 143 144 144 TRACE_ENTRY("%p %zd", sid, sidlen); 145 145 CHECK_PARAMS_DO( sid && sidlen, return NULL ); 146 146 147 147 CHECK_MALLOC_DO( sess = malloc(sizeof(struct session)), return NULL ); 148 148 memset(sess, 0, sizeof(struct session)); 149 149 150 150 sess->eyec = SI_EYEC; 151 151 152 152 sess->sid = sid; 153 153 sess->sidlen = sidlen; 154 154 sess->hash = hash; 155 155 fd_list_init(&sess->chain_h, sess); 156 156 157 157 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &sess->timeout), return NULL ); 158 158 sess->timeout.tv_sec += SESS_DEFAULT_LIFETIME; 159 159 fd_list_init(&sess->expire, sess); 160 160 161 161 CHECK_POSIX_DO( pthread_mutex_init(&sess->stlock, NULL), return NULL ); 162 162 fd_list_init(&sess->states, sess); 163 163 164 164 return sess; 165 165 } … … 175 175 free(s); 176 176 } 177 177 178 178 /* The expiry thread */ 179 179 static void * exp_fct(void * arg) … … 181 181 fd_log_threadname ( "Session/expire" ); 182 182 TRACE_ENTRY( "" ); 183 184 183 184 185 185 do { 186 186 struct timespec now; 187 187 struct session * first; 188 188 189 189 CHECK_POSIX_DO( pthread_mutex_lock(&exp_lock), break ); 190 190 pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); 191 again: 191 again: 192 192 /* Check if there are expiring sessions available */ 193 193 if (FD_IS_LIST_EMPTY(&exp_sentinel)) { … … 197 197 goto again; 198 198 } 199 199 200 200 /* Get the pointer to the session that expires first */ 201 201 first = (struct session *)(exp_sentinel.next->o); 202 202 ASSERT( VALIDATE_SI(first) ); 203 203 204 204 /* Get the current time */ 205 205 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), break ); … … 207 207 /* If first session is not expired, we just wait until it happens */ 208 208 if ( TS_IS_INFERIOR( &now, &first->timeout ) ) { 209 210 CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cond, &exp_lock, &first->timeout ), 209 CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cond, &exp_lock, &first->timeout ), 211 210 ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */, 212 211 /* on other error, */ break ); 213 212 214 213 /* on wakeup, loop */ 215 214 goto again; 216 215 } 217 216 218 217 /* Now, the first session in the list is expired; destroy it */ 219 218 pthread_cleanup_pop( 0 ); 220 219 CHECK_POSIX_DO( pthread_mutex_unlock(&exp_lock), break ); 221 220 222 221 CHECK_FCT_DO( fd_sess_destroy( &first ), break ); 223 222 224 223 } while (1); 225 224 226 225 TRACE_DEBUG(INFO, "A system error occurred in session module! Expiry thread is terminating..."); 227 226 ASSERT(0); 228 227 return NULL; 229 228 } 230 231 229 230 232 231 233 232 /********************************************************************************************************/ … … 237 236 { 238 237 int i; 239 238 240 239 TRACE_ENTRY( "" ); 241 240 242 241 /* Initialize the global counters */ 243 242 sid_h = (uint32_t) time(NULL); 244 243 sid_l = 0; 245 244 246 245 /* Initialize the hash table */ 247 246 for (i = 0; i < sizeof(sess_hash) / sizeof(sess_hash[0]); i++) { … … 249 248 CHECK_POSIX( pthread_mutex_init(&sess_hash[i].lock, NULL) ); 250 249 } 251 250 252 251 return 0; 253 252 } … … 258 257 /* Start session garbage collector (expiry) */ 259 258 CHECK_POSIX( pthread_create(&exp_thr, NULL, exp_fct, NULL) ); 260 259 261 260 return 0; 262 261 } … … 267 266 TRACE_ENTRY(""); 268 267 CHECK_FCT_DO( fd_thr_term(&exp_thr), /* continue */ ); 269 268 270 269 /* Destroy all sessions in the hash table, and the hash table itself? -- How to do it without a race condition ? */ 271 270 272 271 return; 273 272 } … … 277 276 { 278 277 struct session_handler *new; 279 278 280 279 TRACE_ENTRY("%p %p", handler, cleanup); 281 280 282 281 CHECK_PARAMS( handler && cleanup ); 283 282 284 283 CHECK_MALLOC( new = malloc(sizeof(struct session_handler)) ); 285 284 memset(new, 0, sizeof(struct session_handler)); 286 285 287 286 CHECK_POSIX( pthread_mutex_lock(&hdl_lock) ); 288 287 new->id = ++hdl_id; 289 288 CHECK_POSIX( pthread_mutex_unlock(&hdl_lock) ); 290 289 291 290 new->eyec = SH_EYEC; 292 291 new->cleanup = cleanup; 293 292 new->state_dump = dumper; 294 293 new->opaque = opaque; 295 294 296 295 *handler = new; 297 296 return 0; 298 297 } 299 298 300 /* Destroy a handler, and all states attached to this handler. This operation is very slow but we don't care since it's rarely used. 299 /* Destroy a handler, and all states attached to this handler. This operation is very slow but we don't care since it's rarely used. 301 300 * Note that it's better to call this function after all sessions have been deleted... */ 302 301 int fd_sess_handler_destroy ( struct session_handler ** handler, void ** opaque ) … … 306 305 struct fd_list deleted_states = FD_LIST_INITIALIZER( deleted_states ); 307 306 int i; 308 307 309 308 TRACE_ENTRY("%p", handler); 310 309 CHECK_PARAMS( handler && VALIDATE_SH(*handler) ); 311 310 312 311 del = *handler; 313 312 *handler = NULL; 314 313 315 314 del->eyec = 0xdead; /* The handler is not valid anymore for any other operation */ 316 315 317 316 /* Now find all sessions with data registered for this handler, and move this data to the deleted_states list. */ 318 317 for (i = 0; i < sizeof(sess_hash) / sizeof(sess_hash[0]); i++) { 319 318 struct fd_list * li_si; 320 319 CHECK_POSIX( pthread_mutex_lock(&sess_hash[i].lock) ); 321 320 322 321 for (li_si = sess_hash[i].sentinel.next; li_si != &sess_hash[i].sentinel; li_si = li_si->next) { /* for each session in the hash line */ 323 322 struct fd_list * li_st; … … 341 340 CHECK_POSIX( pthread_mutex_unlock(&sess_hash[i].lock) ); 342 341 } 343 342 344 343 /* Now, delete all states after calling their cleanup handler */ 345 344 while (!FD_IS_LIST_EMPTY(&deleted_states)) { … … 350 349 free(st); 351 350 } 352 351 353 352 if (opaque) 354 353 *opaque = del->opaque; 355 354 356 355 /* Free the handler */ 357 356 free(del); 358 357 359 358 return 0; 360 359 } … … 372 371 int found = 0; 373 372 int ret = 0; 374 373 375 374 TRACE_ENTRY("%p %p %zd %p %zd", session, diamid, diamidlen, opt, optlen); 376 375 CHECK_PARAMS( session && (diamid || opt) ); 377 376 378 if (diamid) { 377 if (diamid) { 379 378 if (!diamidlen) { 380 379 diamidlen = strlen(diamid); 381 } 380 } 382 381 /* We check if the string is a valid DiameterIdentity */ 383 382 CHECK_PARAMS( fd_os_is_valid_DiameterIdentity((uint8_t *)diamid, diamidlen) ); … … 385 384 diamidlen = 0; 386 385 } 387 if (opt) { 386 if (opt) { 388 387 if (!optlen) { 389 388 optlen = strlen((char *)opt); … … 394 393 optlen = 0; 395 394 } 396 395 397 396 /* Ok, first create the identifier for the string */ 398 397 if (diamid == NULL) { … … 410 409 sidlen++; /* space for the final \0 also */ 411 410 CHECK_MALLOC( sid = malloc(sidlen) ); 412 411 413 412 CHECK_POSIX( pthread_mutex_lock(&sid_lock) ); 414 413 if ( ++sid_l == 0 ) /* overflow */ … … 417 416 sid_l_cpy = sid_l; 418 417 CHECK_POSIX( pthread_mutex_unlock(&sid_lock) ); 419 418 420 419 if (opt) { 421 420 sidlen = snprintf((char*)sid, sidlen, "%.*s;%u;%u;%.*s", (int)diamidlen, diamid, sid_h_cpy, sid_l_cpy, (int)optlen, opt); … … 424 423 } 425 424 } 426 425 427 426 hash = fd_os_hash(sid, sidlen); 428 427 429 428 /* Now find the place to add this object in the hash table. */ 430 429 CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash) ) ); 431 430 pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); 432 431 433 432 for (li = H_LIST(hash)->next; li != H_LIST(hash); li = li->next) { 434 433 int cmp; 435 434 struct session * s = (struct session *)(li->o); 436 435 437 436 /* The list is ordered by hash and sid (in case of collisions) */ 438 437 if (s->hash < hash) … … 440 439 if (s->hash > hash) 441 440 break; 442 441 443 442 cmp = fd_os_cmp(s->sid, s->sidlen, sid, sidlen); 444 443 if (cmp < 0) … … 446 445 if (cmp > 0) 447 446 break; 448 447 449 448 /* A session with the same sid was already in the hash table */ 450 449 found = 1; … … 452 451 break; 453 452 } 454 453 455 454 /* If the session did not exist, we can create it & link it in global tables */ 456 455 if (!found) { … … 461 460 goto out; 462 461 } ); 463 462 464 463 fd_list_insert_before(li, &sess->chain_h); /* hash table */ 465 464 sess->msg_cnt++; 466 465 } else { 467 466 free(sid); 468 469 CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); 467 468 CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); 470 469 (*session)->msg_cnt++; 471 CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); 472 470 CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); 471 473 472 /* it was found: was it previously destroyed? */ 474 473 if ((*session)->is_destroyed == 0) { … … 479 478 sess = *session; 480 479 sess->is_destroyed = 0; 481 480 482 481 /* update the expiry time */ 483 482 CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &sess->timeout), { ASSERT(0); } ); … … 485 484 } 486 485 } 487 486 488 487 /* We must insert in the expiry list */ 489 488 CHECK_POSIX( pthread_mutex_lock( &exp_lock ) ); … … 512 511 pthread_cleanup_pop(0); 513 512 CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) ); 514 513 515 514 if (ret) /* in case of error */ 516 515 return ret; 517 516 518 517 *session = sess; 519 518 return 0; … … 524 523 { 525 524 int ret; 526 525 527 526 TRACE_ENTRY("%p %zd %p %p", sid, len, session, new); 528 527 CHECK_PARAMS( sid && session ); 529 528 530 529 if (!fd_os_is_valid_os0(sid,len)) { 531 530 TRACE_DEBUG(INFO, "Warning: a Session-Id value contains \\0 chars... (len:%zd, begin:'%.*s') => Debug messages may be truncated.", len, (int)len, sid); 532 531 } 533 532 534 533 /* All the work is done in sess_new */ 535 534 ret = fd_sess_new ( session, NULL, 0, sid, len ); … … 538 537 case EALREADY: 539 538 break; 540 539 541 540 default: 542 541 CHECK_FCT(ret); 543 542 } 544 543 545 544 if (new) 546 545 *new = ret ? 0 : 1; 547 546 548 547 return 0; 549 548 } … … 553 552 { 554 553 TRACE_ENTRY("%p %p", session, sid); 555 554 556 555 CHECK_PARAMS( VALIDATE_SI(session) && sid ); 557 556 558 557 *sid = session->sid; 559 558 if (sidlen) 560 559 *sidlen = session->sidlen; 561 560 562 561 return 0; 563 562 } … … 567 566 { 568 567 struct fd_list * li; 569 568 570 569 TRACE_ENTRY("%p %p", session, timeout); 571 570 CHECK_PARAMS( VALIDATE_SI(session) && timeout ); 572 571 573 572 /* Lock -- do we need to lock the hash table as well? I don't think so... */ 574 573 CHECK_POSIX( pthread_mutex_lock( &exp_lock ) ); 575 574 pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); 576 575 577 576 /* Update the timeout */ 578 577 fd_list_unlink(&session->expire); 579 578 memcpy(&session->timeout, timeout, sizeof(struct timespec)); 580 579 581 580 /* Find the new position in expire list. We take it in normal order */ 582 581 for (li = exp_sentinel.next; li != &exp_sentinel; li = li->next) { … … 598 597 pthread_cleanup_pop(0); 599 598 CHECK_POSIX( pthread_mutex_unlock( &exp_lock ) ); 600 599 601 600 return 0; 602 601 } … … 609 608 os0_t sid; 610 609 int ret = 0; 611 610 612 611 /* place to save the list of states to be cleaned up. We do it after finding them to avoid deadlocks. the "o" field becomes a copy of the sid. */ 613 612 struct fd_list deleted_states = FD_LIST_INITIALIZER( deleted_states ); 614 613 615 614 TRACE_ENTRY("%p", session); 616 615 CHECK_PARAMS( session && VALIDATE_SI(*session) ); 617 616 618 617 sess = *session; 619 618 *session = NULL; 620 619 621 620 /* Lock the hash line */ 622 621 CHECK_POSIX( pthread_mutex_lock( H_LOCK(sess->hash) ) ); 623 622 pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(sess->hash) ); 624 623 625 624 /* Unlink from the expiry list */ 626 625 CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); 626 pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); 627 627 if (!FD_IS_LIST_EMPTY(&sess->expire)) { 628 628 sess_cnt--; 629 629 fd_list_unlink( &sess->expire ); /* no need to signal the condition here */ 630 630 } 631 pthread_cleanup_pop(0); 631 632 CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); 632 633 633 634 /* Now move all states associated to this session into deleted_states */ 634 635 CHECK_POSIX_DO( pthread_mutex_lock( &sess->stlock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); … … 639 640 } 640 641 CHECK_POSIX_DO( pthread_mutex_unlock( &sess->stlock ), { ASSERT(0); /* otherwise cleanup handler is not pop'd */ } ); 641 642 642 643 /* Mark the session as destroyed */ 643 644 destroy_now = (sess->msg_cnt == 0); … … 651 652 pthread_cleanup_pop(0); 652 653 CHECK_POSIX( pthread_mutex_unlock( H_LOCK(sess->hash) ) ); 653 654 654 655 if (ret) 655 656 return ret; 656 657 657 658 /* Now, really delete the states */ 658 659 while (!FD_IS_LIST_EMPTY(&deleted_states)) { … … 663 664 free(st); 664 665 } 665 666 666 667 /* Finally, destroy the session itself, if it is not referrenced by any message anymore */ 667 668 if (destroy_now) { … … 670 671 free(sid); 671 672 } 672 673 673 674 return 0; 674 675 } … … 680 681 uint32_t hash; 681 682 int destroy_now = 0; 682 683 683 684 TRACE_ENTRY("%p", session); 684 685 CHECK_PARAMS( session && VALIDATE_SI(*session) ); 685 686 686 687 sess = *session; 687 688 hash = sess->hash; 688 689 *session = NULL; 689 690 690 691 CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash) ) ); 691 692 pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); … … 693 694 pthread_cleanup_push( fd_cleanup_mutex, &sess->stlock ); 694 695 CHECK_POSIX_DO( pthread_mutex_lock( &exp_lock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } ); 695 696 pthread_cleanup_push( fd_cleanup_mutex, &exp_lock ); 697 696 698 /* We only do something if the states list is empty */ 697 699 if (FD_IS_LIST_EMPTY(&sess->states)) { … … 706 708 } 707 709 } 708 710 711 pthread_cleanup_pop(0); 709 712 CHECK_POSIX_DO( pthread_mutex_unlock( &exp_lock ), { ASSERT(0); /* otherwise, cleanup not poped on FreeBSD */ } ); 710 713 pthread_cleanup_pop(0); … … 712 715 pthread_cleanup_pop(0); 713 716 CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) ); 714 717 715 718 if (destroy_now) 716 719 del_session(sess); 717 720 718 721 return 0; 719 722 } … … 726 729 int already = 0; 727 730 int ret = 0; 728 731 729 732 TRACE_ENTRY("%p %p %p", handler, session, state); 730 733 CHECK_PARAMS( handler && VALIDATE_SH(handler) && session && VALIDATE_SI(session) && (!session->is_destroyed) && state ); 731 734 732 735 /* Lock the session state list */ 733 736 CHECK_POSIX( pthread_mutex_lock(&session->stlock) ); 734 737 pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); 735 738 736 739 /* Create the new state object */ 737 740 CHECK_MALLOC_DO(new = malloc(sizeof(struct state)), { ret = ENOMEM; goto out; } ); 738 741 memset(new, 0, sizeof(struct state)); 739 742 740 743 new->eyec = SD_EYEC; 741 744 new->state= *state; 742 745 fd_list_init(&new->chain, new); 743 746 new->hdl = handler; 744 747 745 748 /* find place for this state in the list */ 746 749 for (li = session->states.next; li != &session->states; li = li->next) { … … 749 752 if (st->hdl->id < handler->id) 750 753 continue; 751 754 752 755 if (st->hdl->id == handler->id) { 753 756 TRACE_DEBUG(INFO, "A state was already stored for session '%s' and handler '%p', at location %p", session->sid, st->hdl, st->state); 754 757 already = EALREADY; 755 758 } 756 759 757 760 break; 758 761 } 759 762 760 763 if (!already) { 761 764 fd_list_insert_before(li, &new->chain); … … 765 768 } 766 769 out: 767 ; 770 ; 768 771 pthread_cleanup_pop(0); 769 772 CHECK_POSIX( pthread_mutex_unlock(&session->stlock) ); 770 773 771 774 return ret ?: already; 772 775 } … … 777 780 struct fd_list * li; 778 781 struct state * st = NULL; 779 782 780 783 TRACE_ENTRY("%p %p %p", handler, session, state); 781 784 CHECK_PARAMS( handler && VALIDATE_SH(handler) && session && VALIDATE_SI(session) && state ); 782 785 783 786 *state = NULL; 784 787 785 788 /* Lock the session state list */ 786 789 CHECK_POSIX( pthread_mutex_lock(&session->stlock) ); 787 790 pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); 788 791 789 792 /* find the state in the list */ 790 793 for (li = session->states.next; li != &session->states; li = li->next) { 791 794 st = (struct state *)(li->o); 792 795 793 796 /* The list is ordered by handler's id */ 794 797 if (st->hdl->id > handler->id) 795 798 break; 796 799 } 797 800 798 801 /* If we found the state */ 799 802 if (st && (st->hdl == handler)) { … … 802 805 free(st); 803 806 } 804 807 805 808 pthread_cleanup_pop(0); 806 809 CHECK_POSIX( pthread_mutex_unlock(&session->stlock) ); 807 810 808 811 return 0; 809 812 } … … 814 817 TRACE_ENTRY("%p %zd %p %p", sid, len, session, new); 815 818 CHECK_PARAMS( sid && len && session ); 816 819 817 820 /* Get the session object */ 818 821 CHECK_FCT( fd_sess_fromsid_msg ( sid, len, session, new) ); 819 822 820 823 /* Decrease the refcount */ 821 824 CHECK_POSIX( pthread_mutex_lock(&(*session)->stlock) ); 822 825 (*session)->msg_cnt--; /* was increased in fd_sess_new */ 823 826 CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); 824 827 825 828 /* Done */ 826 829 return 0; … … 836 839 session->msg_cnt++; 837 840 CHECK_POSIX( pthread_mutex_unlock(&session->stlock) ); 838 841 839 842 return 0; 840 843 } … … 844 847 int reclaim; 845 848 uint32_t hash; 846 849 847 850 TRACE_ENTRY("%p", session); 848 851 CHECK_PARAMS( session && VALIDATE_SI(*session) ); 849 852 850 853 /* Lock the hash line to avoid possibility that session is freed while we are reclaiming */ 851 854 hash = (*session)->hash; 852 855 CHECK_POSIX( pthread_mutex_lock( H_LOCK(hash)) ); 853 pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); 856 pthread_cleanup_push( fd_cleanup_mutex, H_LOCK(hash) ); 854 857 855 858 /* Update the msg refcount */ … … 858 861 (*session)->msg_cnt = reclaim - 1; 859 862 CHECK_POSIX( pthread_mutex_unlock(&(*session)->stlock) ); 860 863 861 864 /* Ok, now unlock the hash line */ 862 865 pthread_cleanup_pop( 0 ); 863 866 CHECK_POSIX( pthread_mutex_unlock( H_LOCK(hash) ) ); 864 867 865 868 /* and reclaim if no message references the session anymore */ 866 869 if (reclaim == 1) { … … 878 881 { 879 882 FD_DUMP_HANDLE_OFFSET(); 880 883 881 884 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{session}(@%p): ", session), return NULL); 882 885 883 886 if (!VALIDATE_SI(session)) { 884 887 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); … … 890 893 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%zd) h:%x m:%d d:%d to:%s.%06ld", 891 894 session->sid, session->sidlen, session->hash, session->msg_cnt, session->is_destroyed, 892 timebuf, session->timeout.tv_nsec/1000), 895 timebuf, session->timeout.tv_nsec/1000), 893 896 return NULL); 894 897 895 898 if (with_states) { 896 899 struct fd_list * li; 897 900 CHECK_POSIX_DO( pthread_mutex_lock(&session->stlock), /* ignore */ ); 898 901 pthread_cleanup_push( fd_cleanup_mutex, &session->stlock ); 899 902 900 903 for (li = session->states.next; li != &session->states; li = li->next) { 901 904 struct state * st = (struct state *)(li->o); 902 905 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n {state i:%d}(@%p): ", st->hdl->id, st), return NULL); 903 906 if (st->hdl->state_dump) { 904 CHECK_MALLOC_DO( (*st->hdl->state_dump)( FD_DUMP_STD_PARAMS, st->state), 907 CHECK_MALLOC_DO( (*st->hdl->state_dump)( FD_DUMP_STD_PARAMS, st->state), 905 908 fd_dump_extend( FD_DUMP_STD_PARAMS, "[dumper error]")); 906 909 } else { … … 908 911 } 909 912 } 910 913 911 914 pthread_cleanup_pop(0); 912 915 CHECK_POSIX_DO( pthread_mutex_unlock(&session->stlock), /* ignore */ ); 913 916 } 914 917 } 915 918 916 919 return *buf; 917 920 } … … 920 923 { 921 924 FD_DUMP_HANDLE_OFFSET(); 922 925 923 926 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{sesshdl}(@%p): ", handler), return NULL); 924 927 925 928 if (!VALIDATE_SH(handler)) { 926 929 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID/NULL"), return NULL); … … 929 932 } 930 933 return *buf; 931 } 934 } 932 935 933 936 int fd_sess_getcount(uint32_t *cnt)
Note: See TracChangeset
for help on using the changeset viewer.