CASA/CASA-auth-token/server/utilities/IpcLibs/linux/client/clientreq.cpp
2007-02-06 22:52:44 +00:00

333 lines
8.3 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 = %0X\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 = %0X\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,
uint32_t serverDataLength)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
DbgTrace(1, "ClientReq::processServerData- Start, Obj = %0X\n", this);
// Acquire exclusive access to the object
pthread_mutex_lock(&m_mutex);
// Save server dataetup the ServerData object
m_pServerData = pServerData;
m_serverDataLen = serverDataLength;
// Mark the request as completed
m_completed = true;
// 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);
}
// 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 = %0X\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,
uint32_t *pResponseDataLength)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
int retStatus;
int oldCancelState;
DbgTrace(1, "ClientReq::waitForCompletion- Start, Obj = %0X\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 = %0X\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 = %0X\n", this);
// Check if we encountered any issues
if (m_internalProblem)
{
compStatus = ErrorCompletionStatus;
}
else
{
compStatus = SuccessCompletionStatus;
}
DbgTrace(1, "ClientReq::completionStatus- End, compStatus = %0X\n", compStatus);
return compStatus;
} /*-- ClientReq::completionStatus() --*/
//=========================================================================
//=========================================================================