Exemplo n.º 1
0
Int RcmClient_getReturnMsg_P(RcmClient_Object *obj, const UInt16 msgId,
    RcmClient_Message **returnMsg)
{
    List_Elem *elem;
    Recipient *recipient;
    RcmClient_Packet *packet;
    Bool messageDelivered;
    MessageQ_Msg msgqMsg = NULL;
    Bool messageFound = FALSE;
    Int queueLockAcquired = 0;
    Error_Block eb;
    Int rval;
    Int status = RcmClient_S_SUCCESS;


    Log_print3(Diags_ENTRY,
        "--> "FXNN": (obj=0x%x, msgId=%d, returnMsgPtr=0x%x",
        (IArg)obj, (IArg)msgId, (IArg)returnMsg);

    Error_init(&eb);
    *returnMsg = NULL;

    /* keep trying until message found */
    while (!messageFound) {

        /* acquire the mailbox lock */
        Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb);
        if (Error_check(&eb)) {
            /* TODO */
            goto leave;
        }

        /* search new mail list for message */
        elem = NULL;
        while ((elem = List_next(obj->newMail, elem)) != NULL) {
            packet = getPacketAddrElem(elem);
            if (msgId == packet->msgId) {
                List_remove(obj->newMail, elem);
                *returnMsg = &packet->message;
                messageFound = TRUE;
                break;
            }
        }

        if (messageFound) {
            /* release the mailbox lock */
            Semaphore_post(obj->mbxLock, &eb);
            if (Error_check(&eb)) {
                /* TODO */
            }
        }
        else {
            /* attempt the message queue lock */
            queueLockAcquired = Semaphore_pend(obj->queueLock, 0, &eb);
            if (Error_check(&eb)) {
                /* TODO */
                goto leave;
            }

            if (1 == queueLockAcquired) {
                /*
                 * mailman role
                 */

                /* deliver new mail until message found */
                while (!messageFound) {

                    /* get message from queue if available (non-blocking) */
                    if (NULL == msgqMsg) {
                        rval = MessageQ_get(obj->msgQue, &msgqMsg, 0);

                        if ((MessageQ_E_TIMEOUT != rval) && (rval < 0)) {
                            Log_error0(FXNN": lost return message");
                            status = RcmClient_E_LOSTMSG;
                            goto leave;
                        }
                        Log_print0(Diags_INFO, FXNN": return message received");
                    }

                    while (NULL != msgqMsg) {

                        /* check if message found */
                        packet = getPacketAddrMsgqMsg(msgqMsg);
                        messageFound = (msgId == packet->msgId);

                        if (messageFound) {
                            *returnMsg = &packet->message;

                            /* search wait list for new mailman */
                            elem = NULL;
                            while ((elem =
                                List_next(obj->recipients, elem)) != NULL) {
                                recipient = (Recipient *)elem;
                                if (NULL == recipient->msg) {
                                    /* signal recipient's event */
                                    SemThread_post(SemThread_handle(
                                        &recipient->event), &eb);
                                    break;
                                }
                            }

                            /* release the message queue lock */
                            Semaphore_post(obj->queueLock, &eb);
                            if (Error_check(&eb)) {
                                /* TODO */
                            }

                            /* release the mailbox lock */
                            Semaphore_post(obj->mbxLock, &eb);
                            if (Error_check(&eb)) {
                                /* TODO */
                            }

                            break;
                        }
                        else {
                            /*
                             * deliver message to mailbox
                             */

                            /* search recipient list for message owner */
                            elem = NULL;
                            messageDelivered = FALSE;
                            while ((elem =
                                List_next(obj->recipients, elem)) != NULL) {
                                recipient = (Recipient *)elem;
                                if (recipient->msgId == packet->msgId) {
                                    recipient->msg = &packet->message;
                                    /* signal the recipient's event */
                                    SemThread_post(SemThread_handle(
                                        &recipient->event), &eb);
                                    messageDelivered = TRUE;
                                    break;
                                }
                            }

                            /* add undelivered message to new mail list */
                            if (!messageDelivered) {
                                /* use the elem in the MessageQ header */
                                elem = (List_Elem *)&packet->msgqHeader;
                                List_put(obj->newMail, elem);
                            }
                        }

                        /* get next message from queue if available */
                        rval = MessageQ_get(obj->msgQue, &msgqMsg, 0);

                        if ((MessageQ_E_TIMEOUT != rval) && (rval < 0)) {
                            Log_error0(FXNN": lost return message");
                            status = RcmClient_E_LOSTMSG;
                            goto leave;
                        }
                        Log_print0(Diags_INFO, FXNN": return message received");
                    }

                    if (!messageFound) {
                        /*
                         * message queue empty
                         */

                        /* release the mailbox lock */
                        Semaphore_post(obj->mbxLock, &eb);
                        if (Error_check(&eb)) {
                            /* TODO */
                        }

                        /* get next message, this blocks the thread */
                        rval = MessageQ_get(obj->msgQue, &msgqMsg,
                            MessageQ_FOREVER);

                        if (rval < 0) {
                            Log_error0(FXNN": lost return message");
                            status = RcmClient_E_LOSTMSG;
                            goto leave;
                        }
                        Log_print0(Diags_INFO, FXNN": return message received");

                        if (msgqMsg == NULL) {
                            Log_error0(FXNN": reply message has been lost");
                            status = RcmClient_E_LOSTMSG;
                            goto leave;
                        }

                        /* acquire the mailbox lock */
                        Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb);
                        if (Error_check(&eb)) {
                            goto leave;  /* TODO */
                        }
                    }
                }
            }
            else {
                /* construct recipient on local stack */
                Recipient self;
                self.msgId = msgId;
                self.msg = NULL;
                SemThread_construct(&self.event, 0, NULL, &eb);
                if (Error_check(&eb)) {
                    /* TODO */
                }

                /* add recipient to wait list */
                elem = &self.elem;
                List_put(obj->recipients, elem);

                /* release the mailbox lock */
                Semaphore_post(obj->mbxLock, &eb);
                if (Error_check(&eb)) {
                    /* TODO */
                }

                /* wait on event */
                SemThread_pend(SemThread_handle(&self.event),
                    Semaphore_FOREVER, &eb);
                if (Error_check(&eb)) {
                    /* TODO */
                }

                /* acquire the mailbox lock */
                Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb);
                if (Error_check(&eb)) {
                    goto leave;  /* TODO */
                }

                if (NULL != self.msg) {
                    /* pickup message */
                    *returnMsg = self.msg;
                    messageFound = TRUE;
                }

                /* remove recipient from wait list */
                List_remove(obj->recipients, elem);
                SemThread_destruct(&self.event);

                /* release the mailbox lock */
                Semaphore_post(obj->mbxLock, &eb);
                if (Error_check(&eb)) {
                    /* TODO */
                }
            }
        }
    } /* while (!messageFound) */

leave:
    Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status);
    return(status);
}
Int SystemCfg_deleteLocalResources(Void)
{
    Error_Block eb;
    Int status = 0;
    struct SystemCfg *stateObj = &SystemCfg_State;


    Log_print1(Diags_ENTRY, "--> %s: ()", (IArg)FXNN);

    Error_init(&eb);

    /* unregister heap with MessageQ */
    MessageQ_unregisterHeap(Global_TilerHeapId);

    /* delete heap used for rcm message queue */
    HeapBufMP_delete(&stateObj->heapH);

    /* send done event to remote core */
    Log_print0(Diags_USER1, FXNN": send done event to remote core");

    status = Notify_sendEvent(stateObj->hostProcId, Global_NotifyLineId,
        Global_HostDspEvtNum, Global_EvtDone, TRUE);

    if (status < 0) {
        /* Log_error() */
        Log_print4(Diags_USER8,
            "Error: %s, line %d: %s: Notify_sendEvent() returned error %d",
            (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status);
        goto leave;
    }

    /* wait for done event from remote core */
    Log_print0(Diags_USER1, FXNN": waiting for done event...");

    SemThread_pend(stateObj->semH, SemThread_FOREVER, &eb);

    if (Error_check(&eb)) {
        /* Log_error() */
        Log_print3(Diags_USER8,
            "Error: %s, line %d: %s:  SemThread_pend() returned with error",
            (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN);
        status = -1;
        goto leave;
    }
    Log_print0(Diags_USER1, FXNN": ...received done event");

    /* unregister notify callback */
    status = Notify_unregisterEvent(stateObj->hostProcId, Global_NotifyLineId,
        Global_HostDspEvtNum, SystemCfg_notifyCB__P, (UArg)stateObj);

    if (status < 0) {
        /* Log_error() */
        Log_print4(Diags_USER8,
            "Error: %s, line %d: %s: "
            "Notify_unregisterEventSingle() returned error %d",
            (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status);
        goto leave;
    }

    /* delete sync object */
    if (stateObj->semH != NULL) {
        SemThread_destruct(&stateObj->semObj);
        stateObj->semH = NULL;
    }

leave:
    Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status);
    return(status);
}
Exemplo n.º 3
0
/*
 *  ======== Hello_stop ========
 *
 *  1. send shutdown event
 *  2. wait for shutdown acknowledgement
 *  3. close remote resources
 *  4. handshake close event
 *  5. delete shared resoures
 *  6. send disconnect event (last event sent)
 *  7. wait for disconnect event
 *  8. unregister notify callback
 *  9. delete semaphore object
 */
Int Hello_stop(Void)
{
    Int         status;
    UInt32      event;


    /*
     *  1. send shutdown command (out-of-band)
     */
    status = Notify_sendEvent(Module.remoteProcId, Module.lineId,
        Module.eventId, App_CMD_SHUTDOWN, TRUE);

    if (status < 0) {
        goto leave;
    }


    /*
     *  2. wait for shutdown acknowledgement
     */
    do {
        event = Hello_waitForEvent();

        if (event >= App_E_FAILURE) {
            status = -1;
            goto leave;
        }
    } while (event != App_CMD_SDACK);


    /*
     *  3. close remote resources
     */


    /*
     *  4. handshake close event
     */
    status = Notify_sendEvent(Module.remoteProcId, Module.lineId,
        Module.eventId, App_CMD_CLOSED, TRUE);

    if (status < 0) {
        goto leave;
    }

    do {
        event = Hello_waitForEvent();

        if (event >= App_E_FAILURE) {
            status = -1;
            goto leave;
        }
    } while (event != App_CMD_CLOSED);


    /*
     *  5. delete shared resoures
     */

    /* unregister heap with MessageQ */
    status = MessageQ_unregisterHeap(Global_RcmClientHeapId);

    if (status < 0) {
        goto leave;
    }

    /* delete the message heap */
    status = HeapBufMP_delete(&Module.msgHeap);

    if (status < 0) {
        goto leave;
    }


    /*
     *  6. send disconnect event (last event sent)
     */
    status = Notify_sendEvent(Module.remoteProcId, Module.lineId,
        Module.eventId, App_CMD_DONE, TRUE);

    if (status < 0) {
        goto leave;
    }


    /*
     *  7. wait for disconnect event (last event received)
     */
    do {
        event = Hello_waitForEvent();

        if (event >= App_E_FAILURE) {
            status = -1;
            goto leave;
        }
    } while (event != App_CMD_DONE);


    /*
     *  8. unregister notify callback
     */
    status = Notify_unregisterEventSingle(Module.remoteProcId, Module.lineId,
        Module.eventId);

    if (status < 0) {
        goto leave;
    }


    /*
     *  9. delete semaphore object
     */
    SemThread_destruct(&Module.semS);


leave:
    return(status);
}