Changeset 1379:9f52a841b0c7 in freeDiameter for libfdcore
- Timestamp:
- Jun 20, 2019, 7:07:56 PM (5 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdcore/p_psm.c
r1330 r1379 41 41 - the state machine described in rfc3539#section-3.4 42 42 - the following observations. 43 43 44 44 The delivery of Diameter messages must not always be unordered: order is important at 45 begin ing and end of a connection lifetime. It means we need agility to45 beginning and end of a connection lifetime. It means we need agility to 46 46 switch between "ordering enforced" and "ordering not enforced to counter 47 47 Head of the Line Blocking" modes of operation. … … 50 50 incomplete, because it lacks the SUSPECT state and the 3 DWR/DWA 51 51 exchanges (section 5.1) when the peer recovers from this state. 52 Person nally I don't see the rationale for exchanging 3 messages (why 3?)52 Personally I don't see the rationale for exchanging 3 messages (why 3?) 53 53 but, if we require at least 1 DWR/DWA exchange to be always performed 54 54 after the CER/CEA exchange (and initiated by the peer that sent the … … 97 97 I really cannot see a way to counter this effect by using the ordering 98 98 of the messages, except by applying a timer (state STATE_CLOSING_GRACE). 99 This timer can be also useful when we detect that some messages has not 100 yet received an answer on this link, to give time to the application to 99 This timer can be also useful when we detect that some messages has not 100 yet received an answer on this link, to give time to the application to 101 101 complete the exchange ongoing. 102 102 … … 128 128 TRACE_ENTRY(""); 129 129 CHECK_POSIX( pthread_mutex_lock(&started_mtx) ); 130 awake: 130 awake: 131 131 if (!ret && !started) { 132 132 pthread_cleanup_push( fd_cleanup_mutex, &started_mtx ); … … 160 160 struct fd_list * li; 161 161 CHECK_PARAMS( FD_IS_LIST_EMPTY(&peer->p_actives) ); 162 162 163 163 /* Callback registered by the credential validator (fd_peer_validate_register) */ 164 164 if (peer->p_cb2) { … … 171 171 return 0; 172 172 } 173 173 174 174 /* Insert in the active peers list */ 175 175 CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_activ_peers_rw) ); 176 176 for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) { 177 177 struct fd_peer * next_p = (struct fd_peer *)li->o; 178 int cmp = fd_os_cmp(peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, 178 int cmp = fd_os_cmp(peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen, 179 179 next_p->p_hdr.info.pi_diamid, next_p->p_hdr.info.pi_diamidlen); 180 180 if (cmp < 0) … … 183 183 fd_list_insert_before(li, &peer->p_actives); 184 184 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_activ_peers_rw) ); 185 185 186 186 /* Callback registered when the peer was added, by fd_peer_add */ 187 187 if (peer->p_cb) { … … 191 191 peer->p_cb_data = NULL; 192 192 } 193 193 194 194 /* Start the thread to handle outgoing messages */ 195 195 CHECK_FCT( fd_out_start(peer) ); 196 196 197 197 /* Update the expiry timer now */ 198 198 CHECK_FCT( fd_p_expi_update(peer) ); 199 199 200 200 return 0; 201 201 } … … 206 206 fd_list_unlink( &peer->p_actives ); 207 207 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_activ_peers_rw) ); 208 208 209 209 /* Stop the "out" thread */ 210 210 CHECK_FCT( fd_out_stop(peer) ); 211 211 212 212 /* Failover the messages */ 213 213 if (!skip_failover) { 214 214 fd_peer_failover_msg(peer); 215 215 } 216 216 217 217 return 0; 218 218 } … … 234 234 } 235 235 break; 236 236 237 237 case FDEVP_TERMINATE: 238 238 /* Do not free the string since it is a constant */ 239 239 break; 240 240 241 241 case FDEVP_CNX_INCOMING: { 242 242 struct cnx_incoming * evd = ev->data; … … 256 256 { 257 257 int ret; 258 258 259 259 struct fd_peer * p = (struct fd_peer *)peer; 260 260 261 261 if (!CHECK_PEER(p)) 262 262 return -1; 263 263 264 264 CHECK_POSIX_DO( pthread_mutex_lock(&p->p_state_mtx), return -1 ); 265 265 ret = p->p_state; 266 266 CHECK_POSIX_DO( pthread_mutex_unlock(&p->p_state_mtx), return -1 ); 267 267 268 268 return ret; 269 269 } … … 274 274 { 275 275 int old; 276 276 277 277 TRACE_ENTRY("%p %d(%s)", peer, new_state, STATE_STR(new_state)); 278 278 CHECK_PARAMS( CHECK_PEER(peer) ); 279 279 280 280 old = fd_peer_getstate(peer); 281 281 if (old == new_state) 282 282 return 0; 283 283 284 284 LOG(((old == STATE_OPEN) || (new_state == STATE_OPEN)) ? ((new_state == STATE_SUSPECT || new_state == STATE_CLOSED) ? FD_LOG_ERROR : FD_LOG_NOTICE ): FD_LOG_DEBUG, "'%s'\t-> '%s'\t'%s'", 285 285 STATE_STR(old), 286 286 STATE_STR(new_state), 287 287 peer->p_hdr.info.pi_diamid); 288 289 288 289 290 290 CHECK_POSIX( pthread_mutex_lock(&peer->p_state_mtx) ); 291 291 peer->p_state = new_state; 292 292 CHECK_POSIX( pthread_mutex_unlock(&peer->p_state_mtx) ); 293 293 294 294 if (old == STATE_OPEN) { 295 295 CHECK_FCT( leave_open_state(peer, new_state == STATE_CLOSING_GRACE) ); … … 302 302 CHECK_FCT( enter_open_state(peer) ); 303 303 } 304 304 305 305 if (new_state == STATE_CLOSED) { 306 306 /* Purge event list */ 307 307 fd_psm_events_free(peer); 308 309 /* Reset the counter of pending an wers to send */308 309 /* Reset the counter of pending answers to send */ 310 310 peer->p_reqin_count = 0; 311 312 /* If the peer is not persist ant, we destroy it */311 312 /* If the peer is not persistent, we destroy it */ 313 313 if (peer->p_hdr.info.config.pic_flags.persist == PI_PRST_NONE) { 314 314 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) ); 315 315 } 316 316 } 317 317 318 318 return 0; 319 319 } … … 323 323 { 324 324 TRACE_DEBUG(FULL, "Peer timeout reset to %d seconds%s", delay, add_random ? " (+/- 2)" : "" ); 325 325 326 326 /* Initialize the timer */ 327 327 CHECK_POSIX_DO( clock_gettime( CLOCK_REALTIME, &peer->p_psm_timer ), ASSERT(0) ); 328 328 329 329 if (add_random) { 330 330 if (delay > 2) … … 341 341 } 342 342 } 343 343 344 344 peer->p_psm_timer.tv_sec += delay; 345 345 346 346 #ifdef SLOW_PSM 347 347 /* temporary for debug */ … … 357 357 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), /* continue */ ); 358 358 } 359 359 360 360 fd_p_cnx_abort(peer, terminate); 361 361 362 362 fd_p_ce_clear_cnx(peer, NULL); 363 363 364 364 if (peer->p_receiver) { 365 365 fd_cnx_destroy(peer->p_receiver); 366 366 peer->p_receiver = NULL; 367 367 } 368 368 369 369 if (terminate) { 370 370 fd_psm_events_free(peer); 371 371 CHECK_FCT_DO( fd_fifo_del(&peer->p_events), /* continue */ ); 372 372 } 373 373 374 374 } 375 375 … … 378 378 /* The PSM thread */ 379 379 /************************************************************************/ 380 /* Cancel ation cleanup : set ZOMBIE state in the peer */381 void cleanup_setstate(void * arg) 380 /* Cancellation cleanup : set ZOMBIE state in the peer */ 381 void cleanup_setstate(void * arg) 382 382 { 383 383 struct fd_peer * peer = (struct fd_peer *)arg; … … 389 389 } 390 390 391 /* The state machine thread (control er) */391 /* The state machine thread (controller) */ 392 392 static void * p_psm_th( void * arg ) 393 393 { … … 398 398 void * ev_data; 399 399 int cur_state; 400 400 401 401 CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) ); 402 402 403 403 pthread_cleanup_push( cleanup_setstate, arg ); 404 404 405 405 /* Set the thread name */ 406 406 { … … 409 409 fd_log_threadname ( buf ); 410 410 } 411 411 412 412 /* The state machine starts in CLOSED state */ 413 413 CHECK_POSIX_DO( pthread_mutex_lock(&peer->p_state_mtx), goto psm_end ); … … 417 417 /* Wait that the PSM are authorized to start in the daemon */ 418 418 CHECK_FCT_DO( fd_psm_waitstart(), goto psm_end ); 419 419 420 420 /* Initialize the timer */ 421 421 if (peer->p_flags.pf_responder) { … … 424 424 fd_psm_next_timeout(peer, created_started, 0); 425 425 } 426 426 427 427 psm_loop: 428 428 /* Get next event */ … … 430 430 peer->p_hdr.info.pi_diamid, STATE_STR(fd_peer_getstate(peer))); 431 431 CHECK_FCT_DO( fd_event_timedget(peer->p_events, &peer->p_psm_timer, FDEVP_PSM_TIMEOUT, &event, &ev_sz, &ev_data), goto psm_end ); 432 432 433 433 cur_state = fd_peer_getstate(peer); 434 434 if (cur_state == -1) 435 435 goto psm_end; 436 436 437 437 TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p,%zd)\t'%s'", 438 438 STATE_STR(cur_state), … … 463 463 CHECK_FCT_DO( fd_p_dp_initiate(peer, ev_data), goto psm_end ); 464 464 goto psm_loop; 465 466 /* 465 466 /* 467 467 case STATE_CLOSING: 468 468 case STATE_CLOSING_GRACE: … … 478 478 } 479 479 } 480 480 481 481 /* A message was received */ 482 482 if (event == FDEVP_CNX_MSG_RECV) { … … 485 485 struct fd_cnx_rcvdata rcv_data; 486 486 struct fd_msg_pmdl * pmdl = NULL; 487 487 488 488 rcv_data.buffer = ev_data; 489 489 rcv_data.length = ev_sz; 490 490 pmdl = fd_msg_pmdl_get_inbuf(rcv_data.buffer, rcv_data.length); 491 491 492 492 /* Parse the received buffer */ 493 CHECK_FCT_DO( fd_msg_parse_buffer( (void *)&ev_data, ev_sz, &msg), 493 CHECK_FCT_DO( fd_msg_parse_buffer( (void *)&ev_data, ev_sz, &msg), 494 494 { 495 495 fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, NULL, peer, &rcv_data, pmdl ); … … 498 498 goto psm_loop; 499 499 } ); 500 500 501 501 fd_hook_associate(msg, pmdl); 502 502 CHECK_FCT_DO( fd_msg_source_set( msg, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen), goto psm_end); 503 503 504 504 /* If the current state does not allow receiving messages, just drop it */ 505 505 if (cur_state == STATE_CLOSED) { … … 509 509 goto psm_loop; 510 510 } 511 511 512 512 /* Extract the header */ 513 513 CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), goto psm_end ); 514 514 515 515 /* If it is an answer, associate with the request or drop */ 516 516 if (!(hdr->msg_flags & CMD_FLAG_REQUEST)) { … … 523 523 goto psm_loop; 524 524 } 525 525 526 526 /* Associate */ 527 527 CHECK_FCT_DO( fd_msg_answ_associate( msg, req ), goto psm_end ); 528 529 } 530 528 529 } 530 531 531 /* Log incoming message */ 532 532 fd_hook_call(HOOK_MESSAGE_RECEIVED, msg, peer, NULL, fd_msg_pmdl_get(msg)); 533 533 534 534 if (cur_state == STATE_OPEN_NEW) { 535 535 /* OK, we have received something, so the connection is supposedly now in OPEN state at the remote site */ 536 536 fd_psm_change_state(peer, STATE_OPEN ); 537 537 } 538 538 539 539 /* Now handle non-link-local messages */ 540 540 if (fd_msg_is_routable(msg)) { … … 563 563 CHECK_POSIX_DO( pthread_mutex_unlock(&peer->p_state_mtx), goto psm_end ); 564 564 } 565 565 566 566 /* Requeue to the global incoming queue */ 567 567 CHECK_FCT_DO(fd_fifo_post(fd_g_incoming, &msg), goto psm_end ); … … 572 572 } 573 573 break; 574 574 575 575 /* In other states, we discard the message, it is either old or invalid to send it for the remote peer */ 576 576 case STATE_WAITCNXACK: … … 588 588 goto psm_loop; 589 589 } 590 590 591 591 /* Link-local message: They must be understood by our dictionary, otherwise we return an error */ 592 592 { … … 594 594 int ret = fd_msg_parse_or_error( &msg, &error ); 595 595 if (ret != EBADMSG) { 596 CHECK_FCT_DO( ret, 596 CHECK_FCT_DO( ret, 597 597 { 598 598 char buf[256]; 599 snprintf(buf, sizeof(buf), "%s: An unexpected error occurred while parsing a link-local message", peer->p_hdr.info.pi_diamid); 599 snprintf(buf, sizeof(buf), "%s: An unexpected error occurred while parsing a link-local message", peer->p_hdr.info.pi_diamid); 600 600 fd_hook_call(HOOK_MESSAGE_DROPPED, msg, peer, buf, fd_msg_pmdl_get(msg)); 601 fd_msg_free(msg); 602 goto psm_end; 601 fd_msg_free(msg); 602 goto psm_end; 603 603 } ); 604 604 } else { … … 609 609 char buf[256]; 610 610 /* Only if an error occurred & the message was not saved / dumped */ 611 snprintf(buf, sizeof(buf), "%s: error sending a message", peer->p_hdr.info.pi_diamid); 611 snprintf(buf, sizeof(buf), "%s: error sending a message", peer->p_hdr.info.pi_diamid); 612 612 fd_hook_call(HOOK_MESSAGE_DROPPED, error, peer, buf, fd_msg_pmdl_get(error)); 613 613 CHECK_FCT_DO( fd_msg_free(error), goto psm_end); … … 624 624 } 625 625 } 626 626 627 627 /* Handle the LL message and update the expiry timer appropriately */ 628 628 switch (hdr->msg_code) { 629 629 case CC_CAPABILITIES_EXCHANGE: 630 CHECK_FCT_DO( fd_p_ce_msgrcv(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), 630 CHECK_FCT_DO( fd_p_ce_msgrcv(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), 631 631 { 632 632 if (msg) … … 635 635 } ); 636 636 break; 637 637 638 638 case CC_DISCONNECT_PEER: 639 639 CHECK_FCT_DO( fd_p_dp_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_reset ); … … 642 642 643 643 break; 644 644 645 645 case CC_DEVICE_WATCHDOG: 646 646 CHECK_FCT_DO( fd_p_dw_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_reset ); 647 647 break; 648 648 649 649 default: 650 650 /* Unknown / unexpected / invalid message -- but validated by our dictionary */ … … 665 665 TRACE_DEBUG(INFO, "Received answer with erroneous 'is_routable' result..."); 666 666 } 667 667 668 668 /* Cleanup the message if not done */ 669 669 if (msg) { … … 675 675 } 676 676 }; 677 677 678 678 /* At this point the message must have been fully handled already */ 679 679 if (msg) { … … 683 683 fd_msg_free(msg); 684 684 } 685 685 686 686 goto psm_loop; 687 687 } 688 688 689 689 /* The connection object is broken */ 690 690 if (event == FDEVP_CNX_ERROR) { … … 696 696 CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); 697 697 break; 698 698 699 699 case STATE_WAITCEA: 700 700 case STATE_OPEN: … … 706 706 /* Mark the connection problem */ 707 707 peer->p_flags.pf_cnx_pb = 1; 708 708 709 709 fd_hook_call(HOOK_PEER_CONNECT_FAILED, NULL, peer, "The connection was broken", NULL); 710 710 711 711 /* Destroy the connection, restart the timer to a new connection attempt */ 712 712 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); 713 713 714 714 case STATE_CLOSED: 715 715 goto psm_reset; 716 716 717 717 case STATE_CLOSING: 718 718 /* We sent a DPR so we are terminating, do not wait for DPA */ 719 719 goto psm_end; 720 720 721 721 case STATE_CLOSING_GRACE: 722 722 if (peer->p_flags.pf_localterm) /* initiated here */ 723 723 goto psm_end; 724 724 725 725 fd_psm_cleanup(peer, 0); 726 726 727 727 /* Reset the timer for next connection attempt */ 728 728 fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer)); … … 731 731 goto psm_loop; 732 732 } 733 733 734 734 /* The connection notified a change in endpoints */ 735 735 if (event == FDEVP_CNX_EP_CHANGE) { 736 736 /* We actually don't care if we are in OPEN state here... */ 737 737 738 738 /* Cleanup the remote LL and primary addresses */ 739 739 CHECK_FCT_DO( fd_ep_filter( &peer->p_hdr.info.pi_endpoints, EP_FL_CONF | EP_FL_DISC | EP_FL_ADV ), /* ignore the error */); 740 740 CHECK_FCT_DO( fd_ep_clearflags( &peer->p_hdr.info.pi_endpoints, EP_FL_PRIMARY ), /* ignore the error */); 741 741 742 742 /* Get the new ones */ 743 743 CHECK_FCT_DO( fd_cnx_getremoteeps(peer->p_cnxctx, &peer->p_hdr.info.pi_endpoints), /* ignore the error */); 744 744 745 745 /* We do not support local endpoints change currently, but it could be added here if needed (refresh fd_g_config->cnf_endpoints) */ 746 746 { … … 750 750 free(buf); 751 751 } 752 752 753 753 /* Done */ 754 754 goto psm_loop; 755 755 } 756 756 757 757 /* A new connection was established and CER containing this peer id was received */ 758 758 if (event == FDEVP_CNX_INCOMING) { 759 759 struct cnx_incoming * params = ev_data; 760 760 ASSERT(params); 761 761 762 762 /* Handle the message */ 763 763 CHECK_FCT_DO( fd_p_ce_handle_newCER(¶ms->cer, peer, ¶ms->cnx, params->validate), goto psm_end ); 764 764 765 765 /* Cleanup if needed */ 766 766 if (params->cnx) { … … 772 772 params->cer = NULL; 773 773 } 774 774 775 775 /* Loop */ 776 776 free(ev_data); 777 777 goto psm_loop; 778 778 } 779 779 780 780 /* A new connection has been established with the remote peer */ 781 781 if (event == FDEVP_CNX_ESTABLISHED) { 782 782 struct cnxctx * cnx = ev_data; 783 783 784 784 /* Release the resources of the connecting thread */ 785 785 CHECK_POSIX_DO( pthread_join( peer->p_ini_thr, NULL), /* ignore, it is not a big deal */); 786 786 peer->p_ini_thr = (pthread_t)NULL; 787 787 788 788 switch (cur_state) { 789 789 case STATE_WAITCNXACK_ELEC: … … 792 792 fd_p_ce_handle_newcnx(peer, cnx); 793 793 break; 794 794 795 795 default: 796 796 /* Just abort the attempt and continue */ … … 798 798 fd_cnx_destroy(cnx); 799 799 } 800 800 801 801 goto psm_loop; 802 802 } 803 803 804 804 /* A new connection has not been established with the remote peer */ 805 805 if (event == FDEVP_CNX_FAILED) { 806 806 807 807 /* Release the resources of the connecting thread */ 808 808 CHECK_POSIX_DO( pthread_join( peer->p_ini_thr, NULL), /* ignore, it is not a big deal */); 809 809 peer->p_ini_thr = (pthread_t)NULL; 810 810 811 811 switch (cur_state) { 812 812 case STATE_WAITCNXACK_ELEC: … … 816 816 CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); 817 817 break; 818 818 819 819 case STATE_WAITCNXACK: 820 820 /* Go back to CLOSE */ 821 821 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); 822 822 goto psm_reset; 823 823 824 824 default: 825 825 /* Just ignore */ 826 826 TRACE_DEBUG(FULL, "Connection attempt failed but current state is %s, ignoring...", STATE_STR(cur_state)); 827 827 } 828 828 829 829 goto psm_loop; 830 830 } 831 831 832 832 /* The timeout for the current state has been reached */ 833 833 if (event == FDEVP_PSM_TIMEOUT) { … … 838 838 CHECK_FCT_DO( fd_p_dw_timeout(peer), goto psm_end ); 839 839 goto psm_loop; 840 840 841 841 case STATE_CLOSED: 842 842 LOG_D("%s: Connecting...", peer->p_hdr.info.pi_diamid); … … 845 845 CHECK_FCT_DO( fd_p_cnx_init(peer), goto psm_end ); 846 846 goto psm_loop; 847 847 848 848 case STATE_SUSPECT: 849 849 /* Mark the connection problem */ … … 856 856 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); 857 857 goto psm_reset; 858 858 859 859 case STATE_CLOSING_GRACE: 860 860 /* The grace period is completed, now close */ 861 861 if (peer->p_flags.pf_localterm) 862 862 goto psm_end; 863 863 864 864 fd_psm_cleanup(peer, 0); 865 865 /* Reset the timer for next connection attempt */ 866 866 fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer)); 867 867 goto psm_loop; 868 868 869 869 case STATE_WAITCNXACK_ELEC: 870 870 /* Abort the initiating side */ … … 873 873 CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); 874 874 goto psm_loop; 875 875 876 876 default: 877 877 ASSERT(0); /* implementation problem, we did not foresee this case? */ 878 878 } 879 879 } 880 880 881 881 /* Default action : the handling has not yet been implemented. [for debug only] */ 882 882 TRACE_DEBUG(INFO, "Missing handler in PSM for '%s'\t<-- '%s'", STATE_STR(cur_state), fd_pev_str(event)); … … 886 886 fd_psm_cleanup(peer, 0); 887 887 goto psm_loop; 888 888 889 889 psm_end: 890 890 cur_state = fd_peer_getstate(peer); … … 912 912 { 913 913 TRACE_ENTRY("%p", peer); 914 914 915 915 /* Check the peer and state are OK */ 916 916 CHECK_PARAMS( fd_peer_getstate(peer) == STATE_NEW ); 917 917 918 918 /* Create the FIFO for events */ 919 919 CHECK_FCT( fd_fifo_new(&peer->p_events, 0) ); 920 921 /* Create the PSM control er thread */920 921 /* Create the PSM controller thread */ 922 922 CHECK_POSIX( pthread_create( &peer->p_psm, NULL, p_psm_th, peer ) ); 923 923 924 924 /* We're done */ 925 925 return 0; … … 931 931 TRACE_ENTRY("%p", peer); 932 932 CHECK_PARAMS( CHECK_PEER(peer) ); 933 933 934 934 if (fd_peer_getstate(peer) != STATE_ZOMBIE) { 935 935 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, reason) ); … … 944 944 { 945 945 TRACE_ENTRY("%p", peer); 946 946 947 947 /* Cancel PSM thread */ 948 948 CHECK_FCT_DO( fd_thr_term(&peer->p_psm), /* continue */ ); 949 949 950 950 /* Cleanup the data */ 951 951 fd_psm_cleanup(peer, 1); 952 952 953 953 /* Destroy the event list */ 954 954 CHECK_FCT_DO( fd_fifo_del(&peer->p_events), /* continue */ ); 955 955 956 956 /* Remaining cleanups are performed in fd_peer_free */ 957 957 return;
Note: See TracChangeset
for help on using the changeset viewer.