コード例 #1
0
//---------------------------------------------------------
/// SendResponse
///
/// Sends the response either over sockets or shared memory
///
/// \param requestID the requestID to send the response to
/// \param cpsMimeType the mimetype to send the response as
/// \param cpsResponse the response to send
/// \param uResponseSize the size of the response being sent
/// \param bStreaming indicates that the response it to a streaming request
///
/// \return true if the response is 'sent' correctly; false otherwise
//---------------------------------------------------------
bool SendResponse(CommunicationID requestID, const char* cpsMimeType, const char* cpsResponse, unsigned int uResponseSize, bool bStreaming)
{
    // find out if this is a streaming response
    if (bStreaming)
    {
        Log(logTRACE, "Sending response over socket\n");
        // this is a streaming response
        // use the socket for comms

        return SendMimeResponse(requestID, cpsMimeType, cpsResponse, uResponseSize);
    }

    // use Shared memory if this is not a streaming response
    if (smLockPut("PLUGINS_TO_GPS", sizeof(requestID) + ((unsigned long) strlen(cpsMimeType) * sizeof(const char)) + uResponseSize, 3) == false)
    {
        Log(logASSERT, "Not enough space in shared memory for response.\n");
        return false;
    }

    NamedSemaphore semaphore;
    bool opened = semaphore.Open("PLUGINS_TO_GPS_SEMAPHORE");

    if (opened)
    {
        if (semaphore.Signal() == false)
        {
            Log(logWARNING, "Failed to signal PLUGINS_TO_GPS_SEMAPHORE. Response may be lost. Error is %d, Previous count is 0\n", osGetLastSystemError());
        }

        semaphore.Close();
    }
    else
    {
        Log(logWARNING, "Failed to open PLUGINS_TO_GPS_SEMAPHORE. Response may be delayed.\n");
    }

    bool bResult = (smPut("PLUGINS_TO_GPS", &requestID, sizeof(requestID)) &&
                    smPut("PLUGINS_TO_GPS", (void*)cpsMimeType, (unsigned long) strlen(cpsMimeType) * sizeof(const char)) &&
                    smPut("PLUGINS_TO_GPS", (void*)cpsResponse, uResponseSize));

    smUnlockPut("PLUGINS_TO_GPS");

    if (bResult == false)
    {
        Log(logASSERT, "Failed to put part of the response into shared memory\n");
    }
    else
    {
        // remove the request
        RemoveRequest(requestID);
    }

    return bResult;
}
コード例 #2
0
//--------------------------------------------------------------
/// Creates and then waits for the PLUGINS_TO_GPS_SEMAPHORE to be
/// signaled, then reads the responses in PLUGINS_TO_GPS shared
/// memory and sends them to the requester.
/// \param pData should be NULL (it is ignored though)
//--------------------------------------------------------------
void PluginResponseThread::WaitForPluginResponses(void* pData)
{
    PS_UNREFERENCED_PARAMETER(pData);

    //create a semaphore which allows putting at most MAX_SEM_COUNT response into SM;
    NamedSemaphore semaphore;
    semaphore.Create("PLUGINS_TO_GPS_SEMAPHORE");

    bool bEvent;

    for (;;)    // loop forever
    {
        bEvent = semaphore.Wait();

        if (bEvent == false)
        {
            Log(logERROR, "Failed to wait on an event (Error %d). Closing response thread.\n", osGetLastSystemError());
            smClose("PLUGINS_TO_GPS");
            semaphore.Close();
            return;
        }

        // the PLUGINS_TO_GPS_EVENT was signaled
        // retrieve and send the response
        if (smLockGet("PLUGINS_TO_GPS"))
        {
            // read data from shared memory
            CommunicationID requestID = 0;
            char pcMimeType[PS_MAX_PATH];

            // the response was signaled, read out one response
            if (bEvent == true)
            {
                requestID = 0;
                memset(pcMimeType, 0, PS_MAX_PATH);
                char* pResponse = NULL;
                unsigned long uResponseSize = 0;

                LARGE_INTEGER nPreSharedMemoryGetTime;
                OSWrappers::QueryPerformanceCounter(&nPreSharedMemoryGetTime);

                if (smGet("PLUGINS_TO_GPS", &requestID, sizeof(CommunicationID)) == sizeof(CommunicationID))
                {
                    // successfully got the requestID

                    // Get the socket associated with this requestID and remove the socket since we're now donw with it.
                    NetSocket* client_socket = ProcessTracker::Instance()->GetSocketFromHandle(requestID);
                    ProcessTracker::Instance()->RemoveSocketFromMap(requestID);

#ifdef CODEXL_GRAPHICS
#ifdef USE_GRAPHICS_SERVER_STATUS_RETURN_CODES
                    // We can remove this message from the DB as we no longer need to monitor it anymore
                    RequestsInFlightDatabase::Instance()->Remove(client_socket);
#endif
#endif
                    // now try to get the mime type
                    if (smGet("PLUGINS_TO_GPS", &pcMimeType, PS_MAX_PATH) > 0)
                    {
                        // successfully got the mime type

                        // get response size
                        while (uResponseSize == 0)
                        {
                            uResponseSize = smGet("PLUGINS_TO_GPS", NULL, 0);
                        }

                        try
                        {
                            pResponse = new char[uResponseSize];
                            memset(pResponse, 0, uResponseSize * sizeof(char));
                        }
                        catch (std::bad_alloc)
                        {
                            Log(logERROR, "Failed to allocate memory for response of size: %lu\n", uResponseSize);
                            pResponse = NULL;
                        }

                        if (pResponse != NULL)
                        {
                            // Read from shared memory
                            if (smGet("PLUGINS_TO_GPS", pResponse, uResponseSize) == 0)
                            {
                                Log(logERROR, "Failed to get response from sharedMemory.\n");
                                smReset("PLUGINS_TO_GPS");
                            }

#ifdef DEBUG_COMMS_PERFORMANCE
                            // Record the time now
                            CommandTiming* pTiming = CommandTimingManager::Instance()->HandleResponse((NetSocket*)requestID);

                            if (pTiming != NULL)
                            {
                                LARGE_INTEGER nPerformanceCount;
                                QueryPerformanceCounter(&nPerformanceCount);
                                pTiming->SetWebServerRoundTripEnd(nPerformanceCount);    // Must set this one before SetPreSharedMemoryGet
                                pTiming->SetPreSharedMemoryGet(nPreSharedMemoryGetTime);
                                pTiming->SetResponseSize(uResponseSize);
                            }

#endif

                            // Send the data back to the client
                            SendMimeResponse(requestID, pcMimeType, pResponse, uResponseSize, client_socket);

#ifdef DEBUG_COMMS_PERFORMANCE
                            CommandTimingManager::Instance()->IncrementServerLoadingCount(-1);
#endif

                            SAFE_DELETE_ARRAY(pResponse);
                        }
                        else
                        {
                            smReset("PLUGINS_TO_GPS");
                            SendMimeResponse(requestID, "plain/text", "Error: Failed to get response from shared memory\n", 49 * sizeof(char), client_socket);
                        }

                    }
                    else
                    {
                        smReset("PLUGINS_TO_GPS");
                        SendMimeResponse(requestID, "plain/text", "Error: Could not read mime type\n", 32 * sizeof(char), client_socket);
                    }
                }
                else
                {
                    // in this case, we don't know socket the communication was on, so we can't send any errors or even close the socket
                    // just have to let the client time out.
                    smReset("PLUGINS_TO_GPS");
                    Log(logERROR, "Failed to get requestID from sharedMemory.\n");
                }

            } // end while sm has data or no responses have been read

            smUnlockGet("PLUGINS_TO_GPS");

        }
        else
        {
            Log(logERROR, "LockGet Failed\n");
        }
    }
}