/**
 * Handler for heap buf mp destroy API.
 *
 * \param ctp	Thread's associated context information.
 * \param msg	The actual devctl() message.
 * \param ocb	OCB associated with client's session.
 *
 * \return POSIX errno value.
 *
 * \retval EOK		Success.
 * \retval ENOTSUP	Unsupported devctl().
 */
int syslink_heapbufmp_destroy(resmgr_context_t *ctp, io_devctl_t *msg, syslink_ocb_t *ocb)
{
	HeapBufMPDrv_CmdArgs *		out  = (HeapBufMPDrv_CmdArgs *) (_DEVCTL_DATA (msg->o));

	out->apiStatus = HeapBufMP_destroy ();
	GT_assert (curTrace, (out->apiStatus >= 0));
    if (out->apiStatus >= 0) {
        /* Remove this call from the list to be cleaned-up */
        remove_ocb_res(ocb, DCMD_HEAPBUFMP_DESTROY, (int)NULL, NULL);
    }

	return (_RESMGR_PTR (ctp, &msg->o, sizeof (msg->o) + sizeof(HeapBufMPDrv_CmdArgs)));
}
/* Function to destroy the System. */
Int
Ipc_destroy (void)
{
    Int            status = Ipc_S_SUCCESS;
    IpcDrv_CmdArgs cmdArgs;

    GT_0trace (curTrace, GT_ENTER, "Ipc_destroy");

    /* TBD: Protect from multiple threads. */
    Ipc_state.setupRefCount--;
    /* This is needed at runtime so should not be in SYSLINK_BUILD_OPTIMIZE. */
    if (Ipc_state.setupRefCount >= 1) {
        /*! @retval Ipc_S_ALREADYSETUP Success: Ipc module has been
                                           already setup in this process */
        status = Ipc_S_ALREADYSETUP;
        GT_1trace (curTrace,
                   GT_1CLASS,
                   "Ipc module has been already setup in this process.\n"
                   "    RefCount: [%d]\n",
                   Ipc_state.setupRefCount);
    }
    else {
#if 0 /* TBD:Temporarily comment. */
        /* Finalize Frame module */
        if (Ipc_state.frameQInitFlag == TRUE) {
            status = FrameQ_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "FrameQ_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.frameQInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize FrameQBufMgr module */
        if (Ipc_state.frameQBufMgrInitFlag == TRUE) {
            status = FrameQBufMgr_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "FrameQBufMgr_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.frameQBufMgrInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize ClientNotifyMgr module */
        if (Ipc_state.clientNotifyMgrInitFlag == TRUE) {
            status = ClientNotifyMgr_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "ClientNotifyMgr_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.clientNotifyMgrInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }
#endif /* TBD: Temporarily comment. */

        /* Finalize LISTMP */
        if (Ipc_state.listMPInitFlag == TRUE) {
            status = ListMP_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_setup",
                                     status,
                                     "ListMpSharedMemory_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.listMPInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

#if 0 /* TBD:Temporarily comment. */
        /* Finalize HeapMultiBuf */
        if (Ipc_state.heapMultiBufInitFlag == TRUE) {
            status = HeapMultiBuf_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "HeapMultiBuf_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.heapMultiBufInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }
#endif /* TBD: Temporarily comment. */

        /* Finalize HeapMemMP */
        if (Ipc_state.heapMemMPInitFlag == TRUE) {
            status = HeapMemMP_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "HeapMemMP_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.heapMemMPInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize heap buf */
        if (Ipc_state.heapBufMPInitFlag == TRUE) {
            status = HeapBufMP_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "HeapBufMP_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.heapBufMPInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize MESSAGEQ */
        if (Ipc_state.messageQInitFlag == TRUE) {
            status = MessageQ_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "MessageQ_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.messageQInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }


        /* Finalize NOTIFY */
        if (Ipc_state.notifyInitFlag == TRUE) {
            status = Notify_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "Notify_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.notifyInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize GateMP */
        if (Ipc_state.gateMPInitFlag == TRUE) {
            status = GateMP_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "GateMP_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.gateMPInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize SharedRegion */
        if (Ipc_state.sharedRegionInitFlag == TRUE) {
            status = SharedRegion_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "SharedRegion_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.sharedRegionInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize PROCMGR */
        if (Ipc_state.procMgrInitFlag == TRUE) {
            status = ProcMgr_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "ProcMgr_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.procMgrInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        /* Finalize NAMESERVER */
        if (Ipc_state.nameServerInitFlag == TRUE) {
            status = NameServer_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "NameServer_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.nameServerInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

#if 0 /* TBD:Temporarily comment. */
        /* Finalize SysMemMgr */
        if (Ipc_state.sysMemMgrInitFlag == TRUE) {
            status = SysMemMgr_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "SysMemMgr_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.sysMemMgrInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }
#endif /* TBD: Temporarily comment. */

        /* Finalize MultiProc */
        if (Ipc_state.multiProcInitFlag == TRUE) {
            /* Destroy the multiProc */
            status = MultiProc_destroy ();
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            if (status < 0) {
                GT_setFailureReason (curTrace,
                                     GT_4CLASS,
                                     "Ipc_destroy",
                                     status,
                                     "MultiProc_destroy failed!");
            }
            else {
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
                Ipc_state.multiProcInitFlag = FALSE;
#if !defined(SYSLINK_BUILD_OPTIMIZE)
            }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
        }

        status = IpcDrv_ioctl (CMD_IPC_DESTROY, &cmdArgs);
#if !defined(SYSLINK_BUILD_OPTIMIZE)
        if (status < 0) {
            GT_setFailureReason (curTrace,
                                 GT_4CLASS,
                                 "Ipc_destroy",
                                 status,
                                 "API (through IOCTL) failed on kernel-side!");
        }
#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */

        UsrUtilsDrv_destroy ();

        /* Close the driver handle. */
        IpcDrv_close ();
    } /* Reference count check */

    GT_1trace (curTrace, GT_LEAVE, "Ipc_destroy", status);

    /*! @retval Ipc_S_SUCCESS Operation successful */
    return status;
}