        -:    0:Source:potrDisconnectPeer.c
        -:    0:Graph:/__w/c-modernization-kit/c-modernization-kit/test/porter/src/libporter/potrDisconnectPeerTest/obj/potrDisconnectPeer.gcno
        -:    0:Data:/__w/c-modernization-kit/c-modernization-kit/test/porter/src/libporter/potrDisconnectPeerTest/obj/potrDisconnectPeer.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:﻿/**
        -:    2: *******************************************************************************
        -:    3: *  @file           potrDisconnectPeer.c
        -:    4: *  @brief          potrDisconnectPeer 関数の実装。
        -:    5: *  @author         c-modernization-kit sample team
        -:    6: *  @date           2026/03/23
        -:    7: *  @version        1.0.0
        -:    8: *
        -:    9: *  @copyright      Copyright (C) CompanyName, Ltd. 2026. All rights reserved.
        -:   10: *
        -:   11: *******************************************************************************
        -:   12: */
        -:   13:
        -:   14:#include <inttypes.h>
        -:   15:#include <porter_const.h>
        -:   16:#include <porter.h>
        -:   17:
        -:   18:#include "../potrContext.h"
        -:   19:#include "../potrPeerTable.h"
        -:   20:#include "../infra/potrLog.h"
        -:   21:
        -:   22:#ifndef _WIN32
        -:   23:    #include <pthread.h>
        -:   24:    typedef pthread_mutex_t PotrMutexLocal;
        -:   25:    #define POTR_MUTEX_LOCK_LOCAL(m)   pthread_mutex_lock(m)
        -:   26:    #define POTR_MUTEX_UNLOCK_LOCAL(m) pthread_mutex_unlock(m)
        -:   27:#else /* _WIN32 */
        -:   28:    #include <winsock2.h>
        -:   29:    typedef CRITICAL_SECTION PotrMutexLocal;
        -:   30:    #define POTR_MUTEX_LOCK_LOCAL(m)   EnterCriticalSection(m)
        -:   31:    #define POTR_MUTEX_UNLOCK_LOCAL(m) LeaveCriticalSection(m)
        -:   32:#endif /* _WIN32 */
        -:   33:
        -:   34:/* doxygen コメントは、ヘッダに記載 */
        1:   35:POTR_EXPORT int POTR_API potrDisconnectPeer(PotrHandle handle, PotrPeerId peer_id)
        -:   36:{
        1:   37:    struct PotrContext_ *ctx = (struct PotrContext_ *)handle;
        -:   38:
        1:   39:    if (ctx == NULL)
        -:   40:    {
    #####:   41:        POTR_LOG(POTR_TRACE_ERROR, "potrDisconnectPeer: handle is NULL");
    #####:   42:        return POTR_ERROR;
        -:   43:    }
        -:   44:
        1:   45:    if (peer_id == POTR_PEER_NA || peer_id == POTR_PEER_ALL)
        -:   46:    {
    #####:   47:        POTR_LOG(POTR_TRACE_ERROR,
        -:   48:                 "potrDisconnectPeer: service_id=%" PRId64 " invalid peer_id=%u"
        -:   49:                 " (POTR_PEER_NA or POTR_PEER_ALL not allowed)",
        -:   50:                 ctx != NULL ? ctx->service.service_id : 0, (unsigned)peer_id);
    #####:   51:        return POTR_ERROR;
        -:   52:    }
        -:   53:
        1:   54:    if (!ctx->is_multi_peer)
        -:   55:    {
        1:   56:        POTR_LOG(POTR_TRACE_ERROR,
        -:   57:                 "potrDisconnectPeer: service_id=%" PRId64 " not in N:1 mode",
        -:   58:                 ctx->service.service_id);
        1:   59:        return POTR_ERROR;
        -:   60:    }
        -:   61:
    #####:   62:    POTR_MUTEX_LOCK_LOCAL(&ctx->peers_mutex);
        -:   63:
        -:   64:    {
    #####:   65:        PotrPeerContext *peer = peer_find_by_id(ctx, peer_id);
        -:   66:
    #####:   67:        if (peer == NULL)
        -:   68:        {
    #####:   69:            POTR_MUTEX_UNLOCK_LOCAL(&ctx->peers_mutex);
    #####:   70:            POTR_LOG(POTR_TRACE_ERROR,
        -:   71:                     "potrDisconnectPeer: service_id=%" PRId64 " peer_id=%u not found",
        -:   72:                     ctx->service.service_id, (unsigned)peer_id);
    #####:   73:            return POTR_ERROR;
        -:   74:        }
        -:   75:
    #####:   76:        POTR_LOG(POTR_TRACE_INFO,
        -:   77:                 "potrDisconnectPeer: service_id=%" PRId64 " peer_id=%u disconnecting",
        -:   78:                 ctx->service.service_id, (unsigned)peer_id);
        -:   79:
        -:   80:        /* FIN を送信 */
    #####:   81:        peer_send_fin(ctx, peer);
        -:   82:
        -:   83:        /* 接続済み状態のみ DISCONNECTED コールバックを発火 */
    #####:   84:        if (peer->health_alive && ctx->callback != NULL)
        -:   85:        {
    #####:   86:            peer->health_alive = 0;
    #####:   87:            ctx->callback(ctx->service.service_id, peer->peer_id,
        -:   88:                          POTR_EVENT_DISCONNECTED, NULL, 0);
        -:   89:        }
        -:   90:
        -:   91:        /* ピアリソースを解放 */
    #####:   92:        peer_free(ctx, peer);
        -:   93:    }
        -:   94:
    #####:   95:    POTR_MUTEX_UNLOCK_LOCAL(&ctx->peers_mutex);
    #####:   96:    return POTR_SUCCESS;
        -:   97:}
