354 lines
8.9 KiB
C++
354 lines
8.9 KiB
C++
|
/***********************************************************************
|
||
|
*
|
||
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Lesser General Public
|
||
|
* License as published by the Free Software Foundation; version 2.1
|
||
|
* of the License.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library Lesser General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Lesser General Public
|
||
|
* License along with this library; if not, Novell, Inc.
|
||
|
*
|
||
|
* To contact Novell about this file by physical or electronic mail,
|
||
|
* you may find current contact information at www.novell.com.
|
||
|
*
|
||
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||
|
*
|
||
|
***********************************************************************/
|
||
|
|
||
|
|
||
|
//===[ Include files ]=====================================================
|
||
|
|
||
|
#include "ipcint.h"
|
||
|
#include "cchannel.h"
|
||
|
#include "clientreq.h"
|
||
|
|
||
|
|
||
|
//===[ External data ]=====================================================
|
||
|
|
||
|
//===[ External prototypes ]===============================================
|
||
|
|
||
|
//===[ Manifest constants ]================================================
|
||
|
|
||
|
//===[ Type definitions ]==================================================
|
||
|
|
||
|
//===[ Function prototypes ]===============================================
|
||
|
|
||
|
//===[ Global variables ]==================================================
|
||
|
|
||
|
//===[ Type definitions ]==================================================
|
||
|
|
||
|
//===[ Function prototypes ]===============================================
|
||
|
|
||
|
//===[ Global variables ]==================================================
|
||
|
|
||
|
//
|
||
|
// Object Counters
|
||
|
//
|
||
|
unsigned long numClientReqObjects = 0;
|
||
|
|
||
|
|
||
|
//++=======================================================================
|
||
|
ClientReq::ClientReq(
|
||
|
uint32_t reqId) :
|
||
|
|
||
|
m_reqId (reqId),
|
||
|
m_pServerData (NULL),
|
||
|
m_submitThreadActive (true),
|
||
|
m_completed (false),
|
||
|
m_internalProblem (false)
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// L2
|
||
|
//=======================================================================--
|
||
|
{
|
||
|
DbgTrace(1, "ClientReq::ClientReq- Start, Obj = %08X\n", this);
|
||
|
|
||
|
// Initialize the mutex
|
||
|
if (pthread_mutex_init(&m_mutex, NULL) != 0)
|
||
|
{
|
||
|
DbgTrace(0, "ClientReq::ClientReq- Mutex initialization failed\n", 0);
|
||
|
|
||
|
// Throw exception
|
||
|
throw bad_alloc();
|
||
|
}
|
||
|
|
||
|
// Initialize the condition
|
||
|
if (pthread_cond_init(&m_condition, NULL) != 0)
|
||
|
{
|
||
|
DbgTrace(0, "ClientReq::ClientReq- Condition initialization failed\n", 0);
|
||
|
|
||
|
// Destroy the allocated mutex
|
||
|
pthread_mutex_destroy(&m_mutex);
|
||
|
|
||
|
// Throw exception
|
||
|
throw bad_alloc();
|
||
|
}
|
||
|
|
||
|
// Increment the object count
|
||
|
InterlockedIncrement(&numClientReqObjects);
|
||
|
|
||
|
DbgTrace(1, "ClientReq::ClientReq- End\n", 0);
|
||
|
|
||
|
} /*-- ClientReq::ClientReq() --*/
|
||
|
|
||
|
|
||
|
//++=======================================================================
|
||
|
ClientReq::~ClientReq(void)
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// L2
|
||
|
//=======================================================================--
|
||
|
{
|
||
|
DbgTrace(1, "ClientReq::~ClientReq- Start, Obj = %08X\n", this);
|
||
|
|
||
|
// Cleanup resources allocated for the object
|
||
|
pthread_mutex_destroy(&m_mutex);
|
||
|
pthread_cond_destroy(&m_condition);
|
||
|
|
||
|
// Release any server data that we may have
|
||
|
if (m_pServerData != NULL)
|
||
|
free(m_pServerData);
|
||
|
|
||
|
// Decrement the object count
|
||
|
InterlockedDecrement(&numClientReqObjects);
|
||
|
|
||
|
DbgTrace(1, "ClientReq::~ClientReq- End\n", 0);
|
||
|
|
||
|
} /*-- ClientReq::~ClientReq() --*/
|
||
|
|
||
|
|
||
|
//++=======================================================================
|
||
|
void
|
||
|
ClientReq::processServerData(
|
||
|
char *pServerData,
|
||
|
int serverDataLength)
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// L2
|
||
|
//=======================================================================--
|
||
|
{
|
||
|
DbgTrace(1, "ClientReq::processServerData- Start, Obj = %08X\n", this);
|
||
|
|
||
|
// Acquire exclusive access to the object
|
||
|
pthread_mutex_lock(&m_mutex);
|
||
|
|
||
|
try {
|
||
|
|
||
|
// Save server dataetup the ServerData object
|
||
|
m_pServerData = pServerData;
|
||
|
m_serverDataLen = serverDataLength;
|
||
|
|
||
|
// Check if we must awaken the thread that submitted the request
|
||
|
// so that it can service the server data.
|
||
|
if (!m_submitThreadActive)
|
||
|
{
|
||
|
// The submit thread is not active, awaken it.
|
||
|
m_submitThreadActive = true;
|
||
|
pthread_cond_signal(&m_condition);
|
||
|
}
|
||
|
}
|
||
|
catch(...) {
|
||
|
|
||
|
DbgTrace(0, "ClientReq::processServerData- Exception caught, Obj = %08X\n", this);
|
||
|
|
||
|
// Free the server data buffer
|
||
|
delete[] pServerData;
|
||
|
|
||
|
// Record that we suffered an internal problem and mark the
|
||
|
// request as completed.
|
||
|
m_internalProblem = true;
|
||
|
m_completed = true;
|
||
|
|
||
|
// Check if we must awaken the thread that submitted the request
|
||
|
// so that it can deal with the problem.
|
||
|
if (!m_submitThreadActive)
|
||
|
{
|
||
|
// The submit thread is not active, awaken it.
|
||
|
m_submitThreadActive = true;
|
||
|
pthread_cond_signal(&m_condition);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Release exclusive access to the object
|
||
|
pthread_mutex_unlock(&m_mutex);
|
||
|
|
||
|
DbgTrace(1, "ClientReq::processServerData- End\n", 0);
|
||
|
|
||
|
} /*-- ClientReq::processServerData() --*/
|
||
|
|
||
|
|
||
|
//++=======================================================================
|
||
|
void
|
||
|
ClientReq::processError(void)
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// L2
|
||
|
//=======================================================================--
|
||
|
{
|
||
|
DbgTrace(1, "ClientReq::processError- Start, Obj = %08X\n", this);
|
||
|
|
||
|
// Acquire exclusive access to the object
|
||
|
pthread_mutex_lock(&m_mutex);
|
||
|
|
||
|
// Record that we suffered an internal problem and mark the
|
||
|
// request as completed.
|
||
|
m_internalProblem = true;
|
||
|
m_completed = true;
|
||
|
|
||
|
// Check if we must awaken the thread that submitted the request
|
||
|
// so that it can deal with the problem.
|
||
|
if (!m_submitThreadActive)
|
||
|
{
|
||
|
// The submit thread is not active, awaken it.
|
||
|
m_submitThreadActive = true;
|
||
|
pthread_cond_signal(&m_condition);
|
||
|
}
|
||
|
|
||
|
// Release exclusive access to the object
|
||
|
pthread_mutex_unlock(&m_mutex);
|
||
|
|
||
|
DbgTrace(1, "ClientReq::processError- End\n", 0);
|
||
|
|
||
|
} /*-- ClientReq::processError() --*/
|
||
|
|
||
|
|
||
|
//++=======================================================================
|
||
|
int
|
||
|
ClientReq::waitForCompletion(
|
||
|
char **ppResponseData,
|
||
|
int *pResponseDataLength)
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// L2
|
||
|
//=======================================================================--
|
||
|
{
|
||
|
int retStatus;
|
||
|
int oldCancelState;
|
||
|
|
||
|
DbgTrace(1, "ClientReq::waitForCompletion- Start, Obj = %08X\n", this);
|
||
|
|
||
|
// Make sure that the thread can not be cancelled while executing
|
||
|
// in this routine.
|
||
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldCancelState);
|
||
|
|
||
|
// Acquire exclusive access to the object
|
||
|
pthread_mutex_lock(&m_mutex);
|
||
|
|
||
|
// Continue until the request completes
|
||
|
while (!m_completed)
|
||
|
{
|
||
|
// Wait to be awaken
|
||
|
//
|
||
|
// Indicate that we are no longer active
|
||
|
m_submitThreadActive = false;
|
||
|
pthread_cond_wait(&m_condition, &m_mutex);
|
||
|
}
|
||
|
|
||
|
// Release exclusive access to the object
|
||
|
pthread_mutex_unlock(&m_mutex);
|
||
|
|
||
|
// Determine the parameters that should be returned
|
||
|
if (!m_internalProblem)
|
||
|
{
|
||
|
retStatus = 0;
|
||
|
*ppResponseData = m_pServerData;
|
||
|
*pResponseDataLength = m_serverDataLen;
|
||
|
|
||
|
// Forget about the server data buffer
|
||
|
m_pServerData = NULL;
|
||
|
}
|
||
|
else
|
||
|
retStatus = -1;
|
||
|
|
||
|
DbgTrace(1, "ClientReq::waitForCompletion- End, retStatus = %08X\n", retStatus);
|
||
|
|
||
|
// Restore the threads cancel state
|
||
|
pthread_setcancelstate(oldCancelState, NULL);
|
||
|
|
||
|
return retStatus;
|
||
|
|
||
|
} /*-- ClientReq::waitForCompletion() --*/
|
||
|
|
||
|
|
||
|
//++=======================================================================
|
||
|
ClientReq::CompletionStatus
|
||
|
ClientReq::completionStatus(void)
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// L2
|
||
|
//=======================================================================--
|
||
|
{
|
||
|
CompletionStatus compStatus;
|
||
|
|
||
|
DbgTrace(1, "ClientReq::completionStatus- Start, Obj = %08X\n", this);
|
||
|
|
||
|
// Check if we encountered any issues
|
||
|
if (m_internalProblem)
|
||
|
{
|
||
|
compStatus = ErrorCompletionStatus;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
compStatus = SuccessCompletionStatus;
|
||
|
}
|
||
|
|
||
|
DbgTrace(1, "ClientReq::completionStatus- End, compStatus = %08X\n", compStatus);
|
||
|
|
||
|
return compStatus;
|
||
|
|
||
|
} /*-- ClientReq::completionStatus() --*/
|
||
|
|
||
|
|
||
|
//=========================================================================
|
||
|
//=========================================================================
|
||
|
|