2006-09-01 01:05:25 +02:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
|
|
|
* 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"
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include "casa_s_ipc.h"
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "schannel.h"
|
|
|
|
#include "serverthread.h"
|
|
|
|
#include "serverreq.h"
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Type definitions ]==================================================
|
|
|
|
|
|
|
|
#define MAX_FILE_PATH_LEN 1024
|
|
|
|
|
|
|
|
//
|
|
|
|
// Socket Mapping definitions
|
|
|
|
//
|
|
|
|
#define INVALID_SOCKET -1
|
|
|
|
#define SOCKET_ERROR -1
|
|
|
|
#define LINGER struct linger
|
|
|
|
#define SOCKADDR_IN struct sockaddr_in
|
|
|
|
#define closesocket close
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
|
|
|
|
|
|
|
|
extern unsigned long numServerReqObjects;
|
|
|
|
extern unsigned long numSChannelObjects;
|
|
|
|
|
|
|
|
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
|
|
|
|
// Debug variables
|
|
|
|
int DebugLevel = 0;
|
|
|
|
bool UseSyslog = false;
|
|
|
|
|
|
|
|
// Application Name for logging purposes
|
|
|
|
char unInitialized[] = "Uninitialized";
|
|
|
|
char *pAppName = unInitialized;
|
|
|
|
|
|
|
|
// Indicators
|
|
|
|
bool svcInitialized = false;
|
|
|
|
bool svcStarted = false;
|
|
|
|
bool serverAddressSet = false;
|
|
|
|
|
|
|
|
// Listen Port Number
|
|
|
|
bool use_AF_INET;
|
|
|
|
bool use_PF_UNIX;
|
|
|
|
unsigned short int listenPortNumber = 0;
|
|
|
|
char listenSocketFile[MAX_FILE_PATH_LEN];
|
|
|
|
|
|
|
|
// Listening Socket
|
|
|
|
int listenSocket = INVALID_SOCKET;
|
|
|
|
|
|
|
|
// Operating parameters
|
|
|
|
bool acceptingConnections = true;
|
|
|
|
bool terminating = false;
|
|
|
|
|
|
|
|
// SChannel list
|
|
|
|
list<SChannel*> sChannelList;
|
|
|
|
pthread_mutex_t serverMutex;
|
|
|
|
|
|
|
|
// Mutex for interlocked operations
|
|
|
|
pthread_mutex_t interlockedMutex;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Active Server Request Map - This map contains all of the active ServerReq objects.
|
|
|
|
// The key used to obtain ServerReq object in the map
|
|
|
|
// is the request Id. Note, this id is associated with
|
|
|
|
// a request when ProcessRequest() is called and it does
|
|
|
|
// not have anything to do with the requests rpc id.
|
|
|
|
//
|
|
|
|
typedef map<int32_t, ServerReq*> RSMap;
|
|
|
|
typedef RSMap::iterator RSMapIter;
|
|
|
|
typedef pair<RSMapIter, bool> RSIterBoolPair;
|
|
|
|
RSMap rsMap;
|
|
|
|
int numActiveRequests = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Next request id (Can not be zero)
|
|
|
|
//
|
|
|
|
int32_t nextReqId = 1;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Pending ServerRequests List and count - Server requests are staged on this lists until
|
|
|
|
// they become active.
|
|
|
|
//
|
|
|
|
list<ServerReq*> pendingServerReqList;
|
|
|
|
int numPendingRequests = 0;
|
|
|
|
|
|
|
|
// ServerThreads operating parameters
|
|
|
|
list<ServerThread*> waitingServerThreadList;
|
|
|
|
int waitingServerThreads = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
int
|
|
|
|
ServiceRequest(
|
|
|
|
ServerReq *pServerReq)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L1
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
2006-09-01 07:37:43 +02:00
|
|
|
int retStatus = -1;
|
2006-09-01 01:05:25 +02:00
|
|
|
|
|
|
|
DbgTrace(1, "ServiceRequest- Start\n", 0);
|
|
|
|
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Do not process if trying to terminate
|
|
|
|
if (!terminating)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
|
|
|
|
// Insert the request into the pending server request list
|
|
|
|
pendingServerReqList.push_back(pServerReq);
|
|
|
|
numPendingRequests ++;
|
|
|
|
|
|
|
|
// Check if there is a thread that can be awaken to process the request
|
|
|
|
if (waitingServerThreads)
|
|
|
|
{
|
|
|
|
// There are waiting ServerThreads, remove one from the list
|
|
|
|
// and reduce the waitingServerThreads count.
|
|
|
|
list<ServerThread*>::iterator iter = waitingServerThreadList.begin();
|
|
|
|
ServerThread *pServerThread = *iter;
|
|
|
|
waitingServerThreadList.erase(iter);
|
|
|
|
waitingServerThreads --;
|
|
|
|
|
|
|
|
// Wake up the server thread
|
|
|
|
pServerThread->awaken();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Success
|
|
|
|
retStatus = 0;
|
|
|
|
}
|
|
|
|
catch (...) {
|
|
|
|
DbgTrace(0, "ServiceRequest- Exception caught\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
DbgTrace(1, "ServiceRequest- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
|
|
|
|
} /*-- ServiceRequest() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
AbortPendingRequests(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "AbortPendingRequests- Start\n", 0);
|
|
|
|
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Abort and delete all of the ServerReq in the pendingServerReqList
|
|
|
|
while (numPendingRequests)
|
|
|
|
{
|
|
|
|
list<ServerReq*>::iterator iter = pendingServerReqList.begin();
|
|
|
|
ServerReq *pServerReq = *iter;
|
|
|
|
pendingServerReqList.erase(iter);
|
|
|
|
numPendingRequests --;
|
|
|
|
|
|
|
|
pServerReq->abort();
|
|
|
|
delete pServerReq;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
DbgTrace(1, "AbortPendingRequests- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- AbortPendingRequests() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
AwakenSuspendedServerThreads(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "AwakenSuspendedServerThreads- Start\n", 0);
|
|
|
|
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Awaken all of the ServerThreads in the waitingServerThreadsList
|
|
|
|
while (waitingServerThreads)
|
|
|
|
{
|
|
|
|
list<ServerThread*>::iterator iter = waitingServerThreadList.begin();
|
|
|
|
ServerThread *pServerThread = *iter;
|
|
|
|
waitingServerThreadList.erase(iter);
|
|
|
|
waitingServerThreads --;
|
|
|
|
|
|
|
|
// Wake up the server thread
|
|
|
|
pServerThread->awaken();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
DbgTrace(1, "AwakenSuspendedServerThreads- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- AwakenSuspendedServerThreads() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
RemoveFromSChannelList(
|
|
|
|
SChannel *pSChannel)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
list<SChannel*>::iterator iter;
|
|
|
|
bool objectRemoved = false;
|
|
|
|
|
|
|
|
DbgTrace(1, "RemoveFromSChannelList- Start, Obj = %08X\n", pSChannel);
|
|
|
|
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Find the object in the list
|
|
|
|
if (!sChannelList.empty())
|
|
|
|
{
|
|
|
|
iter = sChannelList.begin();
|
|
|
|
while (iter != sChannelList.end())
|
|
|
|
{
|
|
|
|
if (*iter == pSChannel)
|
|
|
|
{
|
|
|
|
// Object found, remove it from the list.
|
|
|
|
sChannelList.erase(iter);
|
|
|
|
|
|
|
|
// Remember that we removed the object
|
|
|
|
objectRemoved = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Proceed to the next item
|
|
|
|
iter ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
// Check if the object was removed
|
|
|
|
if (objectRemoved == false)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "RemoveFromSChannelList- Error, did not find object in list\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "RemoveFromSChannelList- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- RemoveFromSChannelList() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
ShutdownSChannels(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
list<SChannel*>::iterator iter;
|
|
|
|
SChannel *pSChannel;
|
|
|
|
struct timespec waitTime = {0};
|
|
|
|
|
|
|
|
DbgTrace(1, "ShutdownSChannels- Start\n", 0);
|
|
|
|
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Close all of the SChannels in the SChannelList
|
|
|
|
if (!sChannelList.empty())
|
|
|
|
{
|
|
|
|
iter = sChannelList.begin();
|
|
|
|
while (iter != sChannelList.end())
|
|
|
|
{
|
|
|
|
// Found SChannel in the idle list, close it.
|
|
|
|
(*iter)->closeChannel();
|
|
|
|
|
|
|
|
// Move on to the next item in the list
|
|
|
|
iter ++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
// Loop until all SChannels are gone
|
|
|
|
while (numSChannelObjects != 0)
|
|
|
|
{
|
|
|
|
// Wait for sometime
|
|
|
|
waitTime.tv_sec = 1; // One second
|
|
|
|
nanosleep(&waitTime, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "ShutdownSChannels- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- ShutdownSChannels() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
int
|
|
|
|
OpenSocket(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int openedSocket;
|
|
|
|
|
|
|
|
// Open a domain socket if a listen port number has not
|
|
|
|
// been configured else open a Tcp socket.
|
|
|
|
if (use_PF_UNIX)
|
|
|
|
openedSocket = socket(PF_UNIX, SOCK_STREAM, 0);
|
|
|
|
else
|
|
|
|
openedSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
|
|
|
|
return openedSocket;
|
|
|
|
|
|
|
|
} /*-- OpenSocket() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
int
|
|
|
|
BindSocket(int socketToBind)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int retStatus;
|
|
|
|
|
|
|
|
// Bind domain socket if a listen port number has not
|
|
|
|
// been configured else open a Tcp socket.
|
|
|
|
if (use_PF_UNIX)
|
|
|
|
{
|
|
|
|
struct sockaddr_un listenAddr;
|
|
|
|
|
|
|
|
// Set the file creation mask to 000
|
|
|
|
mode_t prevMask = umask(000);
|
|
|
|
|
|
|
|
// Remove pre-existing socket
|
|
|
|
unlink(listenSocketFile);
|
|
|
|
|
|
|
|
// Setup the address that the daemon will use to listen
|
|
|
|
// for connections.
|
|
|
|
listenAddr.sun_family = AF_UNIX;
|
|
|
|
strcpy(listenAddr.sun_path, listenSocketFile);
|
|
|
|
|
|
|
|
// Perform the bind operation
|
|
|
|
retStatus = bind(socketToBind,
|
|
|
|
(const sockaddr*) &listenAddr,
|
|
|
|
sizeof(listenAddr.sun_family) + strlen(listenAddr.sun_path));
|
|
|
|
|
|
|
|
// Return the file creation mask to its previous value
|
|
|
|
umask(prevMask);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct sockaddr_in listenAddr = {0};
|
|
|
|
int on = 1;
|
|
|
|
|
|
|
|
// Setup the address that the daemon will use to listen
|
|
|
|
// for connections.
|
|
|
|
listenAddr.sin_family = AF_INET;
|
|
|
|
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
listenAddr.sin_port = htons(listenPortNumber);
|
|
|
|
|
|
|
|
// Set the SO_REUSEADDR option on the socket to avoid
|
|
|
|
// problems in case of a re-start.
|
|
|
|
setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
|
|
|
|
|
|
|
// Perform the bind operation
|
|
|
|
retStatus = bind(socketToBind,
|
|
|
|
(const sockaddr*) &listenAddr,
|
|
|
|
sizeof(struct sockaddr_in));
|
|
|
|
}
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
|
|
|
|
} /*-- BindSocket() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
int
|
|
|
|
AcceptConnection(int acceptPendingSocket)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int connectionSocket;
|
|
|
|
socklen_t remoteAddrLen;
|
|
|
|
|
|
|
|
// Use the appropriate address structure when Accepting connection
|
|
|
|
if (use_PF_UNIX)
|
|
|
|
{
|
|
|
|
struct sockaddr_un remoteAddr;
|
|
|
|
remoteAddrLen = sizeof(remoteAddr);
|
|
|
|
|
|
|
|
// Perform the accept operation
|
|
|
|
connectionSocket = accept(acceptPendingSocket,
|
|
|
|
(struct sockaddr*) &remoteAddr,
|
|
|
|
&remoteAddrLen);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct sockaddr_in remoteAddr;
|
|
|
|
remoteAddrLen = sizeof(remoteAddr);
|
|
|
|
|
|
|
|
// Perform the accept operation
|
|
|
|
connectionSocket = accept(acceptPendingSocket,
|
|
|
|
(struct sockaddr*) &remoteAddr,
|
|
|
|
&remoteAddrLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
return connectionSocket;
|
|
|
|
|
|
|
|
} /*-- AcceptConnection() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void
|
|
|
|
ServiceConnections(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
|
|
|
// L2
|
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int connSocket;
|
|
|
|
SChannel *pSChannel;
|
|
|
|
bool sChannelAddedToList = false;
|
|
|
|
|
|
|
|
DbgTrace(1, "ServiceConnections- Start\n", 0);
|
|
|
|
|
|
|
|
// Open listening Tcp socket
|
|
|
|
listenSocket = OpenSocket();
|
|
|
|
if (listenSocket != INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
// Bind the socket
|
|
|
|
if (!BindSocket(listenSocket))
|
|
|
|
{
|
|
|
|
// Socket has been bound to our listen address, now set
|
|
|
|
// the socket in listen mode.
|
|
|
|
if (listen(listenSocket, SOMAXCONN) != SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
// The socket is now in listen mode, start accepting connections.
|
|
|
|
while (acceptingConnections)
|
|
|
|
{
|
|
|
|
pSChannel = NULL;
|
|
|
|
connSocket = AcceptConnection(listenSocket);
|
|
|
|
if (connSocket != INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
// We received a new connection
|
|
|
|
//
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Create a SChannel object to service the connection
|
|
|
|
try {
|
|
|
|
|
|
|
|
pSChannel = new SChannel(connSocket);
|
|
|
|
|
|
|
|
// Associate a smart pointer with the channel to make sure
|
|
|
|
// that it does not go away prematurely while we execute
|
|
|
|
// SChannel::init(), also, this will allow the object to
|
|
|
|
// get cleaned up if its initialization fails.
|
|
|
|
SmartSChannel smartSChannel = pSChannel;
|
|
|
|
|
|
|
|
// SChannel created, insert it into the SChannel list.
|
|
|
|
sChannelList.push_back(pSChannel);
|
|
|
|
sChannelAddedToList = true;
|
|
|
|
|
|
|
|
// Initialize the SChannel
|
|
|
|
if (pSChannel->init())
|
|
|
|
{
|
|
|
|
DbgTrace(0, "ServiceConnections- SChannel intialization failed\n", 0);
|
|
|
|
|
|
|
|
// Remove the SChannel object from the SChannel list
|
|
|
|
sChannelList.pop_back();
|
|
|
|
sChannelAddedToList = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (...) {
|
|
|
|
|
|
|
|
DbgTrace(0, "ServiceConnections- Exception caught\n", 0);
|
|
|
|
|
|
|
|
// Free necessary resources
|
|
|
|
if (pSChannel)
|
|
|
|
{
|
|
|
|
if (sChannelAddedToList)
|
|
|
|
sChannelList.pop_back();
|
|
|
|
delete pSChannel;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
closesocket(connSocket);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Check if accept failed because we got interrupted
|
|
|
|
if (errno == EINTR)
|
|
|
|
{
|
|
|
|
// We got interrupted during the accept, try again.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// This could be because the listen socket got closed.
|
|
|
|
DbgTrace(1, "ServiceConnections- Accept failed, error = %d\n", errno);
|
|
|
|
|
|
|
|
// Break out of the accept loop if the socket indeed got closed
|
|
|
|
if (listenSocket == INVALID_SOCKET)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "ServiceConnections- Listen failed, error = %d\n", errno);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "ServiceConnections- Unable to bind socket, error = %d\n", errno);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close listening socket if necessary
|
|
|
|
if (listenSocket != INVALID_SOCKET)
|
|
|
|
closesocket(listenSocket);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "ServiceConnections- Unable to open socket, error = %d\n", errno);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "ServiceConnections- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- ServiceConnections() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
void* ServiceConnectionsThread(void)
|
|
|
|
//
|
|
|
|
// Arguments:
|
|
|
|
//
|
|
|
|
// Returns:
|
|
|
|
//
|
|
|
|
// Abstract:
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "ServiceConnectionsThread- Start\n", 0);
|
|
|
|
|
|
|
|
// Set the thread in the detached state so that it is cleaned up when it exits
|
|
|
|
pthread_detach(pthread_self());
|
|
|
|
|
|
|
|
// Service connections until no longer necessary
|
|
|
|
ServiceConnections();
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
ShutdownSChannels();
|
|
|
|
|
|
|
|
DbgTrace(1, "ServiceConnectionsThread- End\n", 0);
|
|
|
|
|
|
|
|
// Exit
|
|
|
|
pthread_exit(NULL);
|
|
|
|
|
|
|
|
return 0; // never-reached!
|
|
|
|
|
|
|
|
} /*-- ServiceConnectionsThread() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
int32_t
|
|
|
|
IpcServerGetRequest(void)
|
|
|
|
//
|
|
|
|
// Arguments In: None.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: The id of the pending request.
|
|
|
|
// 0 == Not able to wait for request.
|
|
|
|
//
|
|
|
|
// Abstract: A server thread invokes this method to be informed when
|
|
|
|
// a request is received that needs to be acted upon.
|
|
|
|
//
|
|
|
|
// Notes: The routine blocks until a request becomes available or
|
|
|
|
// until the IpcServer is shutdown.
|
|
|
|
//
|
|
|
|
// An application can execute this method from multiple
|
|
|
|
// threads to allow requests to be process concurrently.
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L1
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t requestId = 0;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerGetRequest- Start\n", 0);
|
|
|
|
|
|
|
|
// Make sure that the service has been started
|
|
|
|
if (!svcStarted)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerGetRequest- Service has not been started\n", 0);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// Instantiate ServerThread object
|
2006-09-01 07:37:43 +02:00
|
|
|
ServerThread serverThread;
|
2006-09-01 01:05:25 +02:00
|
|
|
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Try to find a request to process
|
|
|
|
while (!terminating)
|
|
|
|
{
|
|
|
|
// Make sure that this is initialized to zero
|
|
|
|
requestId = 0;
|
|
|
|
|
|
|
|
// Check if there is a request for us to process
|
|
|
|
if (numPendingRequests)
|
|
|
|
{
|
|
|
|
// Obtain pending request and place it in the active map
|
|
|
|
list<ServerReq*>::iterator iter = pendingServerReqList.begin();
|
|
|
|
ServerReq *pServerReq = *iter;
|
|
|
|
pendingServerReqList.erase(iter);
|
|
|
|
numPendingRequests --;
|
|
|
|
|
|
|
|
// Assign an id to this request and increment
|
|
|
|
// the nextReqId.
|
|
|
|
//
|
|
|
|
// Protect against zero since it is not valid.
|
|
|
|
if (nextReqId != 0)
|
|
|
|
{
|
|
|
|
requestId = nextReqId;
|
|
|
|
nextReqId ++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
requestId = 1;
|
|
|
|
nextReqId = 2;
|
|
|
|
}
|
|
|
|
|
2006-09-01 07:37:43 +02:00
|
|
|
// Place the request in the active request map
|
2006-09-01 01:05:25 +02:00
|
|
|
RSIterBoolPair insertResult = rsMap.insert(make_pair(requestId, pServerReq));
|
|
|
|
if (!insertResult.second)
|
|
|
|
{
|
|
|
|
// Insertion failed
|
|
|
|
DbgTrace(0, "IpcServerGetRequest- Unable to insert ServerReq into map\n", 0);
|
|
|
|
|
|
|
|
// Abort and free the request
|
|
|
|
pServerReq->abort();
|
|
|
|
delete pServerReq;
|
|
|
|
|
|
|
|
// Try again
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Increment the number of active requests
|
|
|
|
numActiveRequests ++;
|
|
|
|
|
|
|
|
// Exit to allow the calling thread to process the request
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// There is not a request for us to process, place us on the waiting
|
|
|
|
// server thread list and wait to be awaken.
|
2006-09-01 07:37:43 +02:00
|
|
|
waitingServerThreadList.push_back(&serverThread);
|
2006-09-01 01:05:25 +02:00
|
|
|
waitingServerThreads ++;
|
2006-09-01 07:37:43 +02:00
|
|
|
serverThread.suspend(&serverMutex);
|
2006-09-01 01:05:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
}
|
|
|
|
catch (...) {
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerGetRequest- Exception caught\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerGetRequest- End, requestId = %08X\n", requestId);
|
|
|
|
|
|
|
|
return requestId;
|
|
|
|
|
|
|
|
} /*-- IpcServerGetRequest() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
int32_t
|
|
|
|
IpcServerGetRequestData(
|
|
|
|
IN int32_t requestId,
|
|
|
|
INOUT char **ppReqData)
|
|
|
|
//
|
|
|
|
// Arguments In: requestId - The id of the request being processed.
|
|
|
|
//
|
|
|
|
// Arguments Out: ppReqData - Pointer to variable that will receive a
|
|
|
|
// pointer to the buffer containing the request
|
|
|
|
// data the client.
|
|
|
|
//
|
|
|
|
// Returns: The length of the request data returned.
|
|
|
|
//
|
|
|
|
// Abstract: Method to obtain the data associated with a particular
|
|
|
|
// request.
|
|
|
|
//
|
|
|
|
// Notes: The returned buffer SHOULD NOT be released by the calling
|
|
|
|
// application.
|
|
|
|
//
|
2006-09-08 01:33:33 +02:00
|
|
|
// The returned buffer always contains a NULL after the
|
|
|
|
// data indicated. You may be able to leverage this to
|
|
|
|
// treat the data as a NULL terminated string in cases
|
|
|
|
// where the request consists of ASCII characters.
|
2006-09-01 07:37:43 +02:00
|
|
|
// L1
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int32_t reqDataLen = 0;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerGetRequestData- Start, requestId = %08X\n", requestId);
|
|
|
|
|
|
|
|
// Make sure that the service has been started
|
|
|
|
if (svcStarted)
|
|
|
|
{
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Find request in the active map
|
|
|
|
RSMapIter iter = rsMap.find(requestId);
|
|
|
|
if (iter != rsMap.end())
|
|
|
|
{
|
|
|
|
// Request was found in the map, obtain a reference to it.
|
|
|
|
ServerReq *pServerReq = iter->second;
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
// Obtain the request data associated with the request
|
|
|
|
reqDataLen = pServerReq->getReqData(ppReqData);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerGetRequestData- Request not found in map\n", 0);
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerGetRequestData- Service has not been started\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerGetRequestData- End, reqDataLen = %08X\n", reqDataLen);
|
|
|
|
|
|
|
|
return reqDataLen;
|
|
|
|
|
|
|
|
} /*-- IpcServerGetRequestData() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
IpcServerCompleteRequest(
|
|
|
|
IN int32_t requestId,
|
|
|
|
IN char *pReplyData)
|
|
|
|
//
|
|
|
|
// Arguments In: requestId - The id of the request being completed.
|
|
|
|
//
|
|
|
|
// pReplyData - Pointer to reply data that must be sent to
|
|
|
|
// the client for this request.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: Nothing.
|
|
|
|
//
|
|
|
|
// Abstract: Method to complete a request being processed.
|
|
|
|
//
|
|
|
|
// Notes: The returned buffer will not NOT be released by the method.
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L1
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "IpcServerCompleteRequest- Start, requestId = %08X\n", requestId);
|
|
|
|
|
|
|
|
// Make sure that the service has been started
|
|
|
|
if (svcStarted)
|
|
|
|
{
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Find request in the active map
|
|
|
|
RSMapIter iter = rsMap.find(requestId);
|
|
|
|
if (iter != rsMap.end())
|
|
|
|
{
|
|
|
|
// Request was found in the map, get a reference to it and
|
|
|
|
// remove it from the map>
|
|
|
|
ServerReq *pServerReq = iter->second;
|
|
|
|
rsMap.erase(iter);
|
|
|
|
numActiveRequests --;
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
// Coomplete the request and delete it.
|
|
|
|
pServerReq->complete(pReplyData);
|
|
|
|
delete pServerReq;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerCompleteRequest- Request not found in map\n", 0);
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerCompleteRequest- Service has not been started\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerCompleteRequest- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- IpcServerCompleteRequest() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
IpcServerAbortRequest(
|
|
|
|
IN int32_t requestId)
|
|
|
|
//
|
|
|
|
// Arguments In: requestId - The id of the request being aborted.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: Nothing.
|
|
|
|
//
|
|
|
|
// Abstract: Method to abort a request being processed.
|
|
|
|
//
|
|
|
|
// Notes:
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L1
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "IpcServerAbortRequest- Start, requestId = %08X\n", requestId);
|
|
|
|
|
|
|
|
// Make sure that the service has been started
|
|
|
|
if (svcStarted)
|
|
|
|
{
|
|
|
|
// Obtain server mutex
|
|
|
|
pthread_mutex_lock(&serverMutex);
|
|
|
|
|
|
|
|
// Find request in the active map
|
|
|
|
RSMapIter iter = rsMap.find(requestId);
|
|
|
|
if (iter != rsMap.end())
|
|
|
|
{
|
|
|
|
// Request was found in the map, get a reference to it and
|
|
|
|
// remove it from the map>
|
|
|
|
ServerReq *pServerReq = iter->second;
|
|
|
|
rsMap.erase(iter);
|
|
|
|
numActiveRequests --;
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
|
|
|
|
// Coomplete the request and delete it.
|
|
|
|
pServerReq->abort();
|
|
|
|
delete pServerReq;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerAbortRequest- Request not found in map\n", 0);
|
|
|
|
|
|
|
|
// Release server mutex
|
|
|
|
pthread_mutex_unlock(&serverMutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerAbortRequest- Service has not been started\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerAbortRequest- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- IpcServerAbortRequest() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
IpcServerStart(void)
|
|
|
|
//
|
|
|
|
// Arguments In: None.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: 0 == Success
|
|
|
|
// -1 == Failure
|
|
|
|
//
|
|
|
|
// Abstract: Method to enable the reception of server requests.
|
|
|
|
//
|
|
|
|
// Note: The service needs to be initialized and the listen address
|
|
|
|
// needs to be set before calling this procedure.
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int retStatus = -1;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerStart- Start\n", 0);
|
|
|
|
|
|
|
|
// Make sure that the listen address has been set
|
|
|
|
if (serverAddressSet)
|
|
|
|
{
|
|
|
|
// Do not do anything if we have already been started
|
|
|
|
if (!svcStarted)
|
|
|
|
{
|
|
|
|
// Create a threat to service connections
|
|
|
|
pthread_t thread;
|
|
|
|
int threadCreateStatus;
|
|
|
|
threadCreateStatus = pthread_create(&thread,
|
|
|
|
NULL,
|
|
|
|
(void*(*)(void*))ServiceConnectionsThread,
|
|
|
|
(void*)NULL);
|
|
|
|
if (threadCreateStatus != 0)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerStart- Unable to create service connections thread, error = %08X\n", threadCreateStatus);
|
|
|
|
retStatus = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Success
|
|
|
|
svcStarted = true;
|
|
|
|
retStatus = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerStart- Either not initialized or the address has not been set\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerStart- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
|
|
|
|
} /*-- IpcServerStart() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
IpcServerSetUnAddress(
|
|
|
|
IN char *pSocketFileName)
|
|
|
|
//
|
|
|
|
// Arguments In: pSocketFileName - Pointer to string containing the name
|
|
|
|
// of the socket file to listen on.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: 0 == Success
|
|
|
|
// -1 == Failure
|
|
|
|
//
|
|
|
|
// Abstract: Method to set the socket file name to utilize for
|
|
|
|
// communicating with the server via DOMAIN sockets.
|
|
|
|
//
|
|
|
|
// Note: The service needs to be initialized before calling this procedure.
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L1
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int retStatus = -1;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerSetUnAddress- Start\n", 0);
|
|
|
|
|
|
|
|
// Verify the input parameters
|
|
|
|
if (pSocketFileName == NULL
|
2006-09-01 07:37:43 +02:00
|
|
|
|| strlen(pSocketFileName) >= sizeof(listenSocketFile))
|
2006-09-01 01:05:25 +02:00
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerSetUnAddress- Invalid input parameter\n", 0);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure that we have been initialized
|
|
|
|
if (svcInitialized)
|
|
|
|
{
|
|
|
|
// Make sure that the address has not already been set.
|
|
|
|
if (serverAddressSet == false)
|
|
|
|
{
|
|
|
|
// Save a copy of the socket file name
|
|
|
|
strcpy(listenSocketFile, pSocketFileName);
|
|
|
|
|
|
|
|
// Remember this
|
|
|
|
serverAddressSet = true;
|
|
|
|
use_AF_INET = false;
|
|
|
|
use_PF_UNIX = true;
|
|
|
|
|
|
|
|
// Success
|
|
|
|
retStatus = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerSetUnAddress- Already set\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerSetUnAddress- Service not yet initialized\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerSetUnAddress- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
|
|
|
|
} /*-- IpcServerSetUnAddress() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
IpcServerSetInAddress(
|
|
|
|
IN unsigned short int listenPort)
|
|
|
|
//
|
|
|
|
// Arguments In: serverPort - Server's listening port number.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: 0 == Success
|
|
|
|
// -1 == Failure
|
|
|
|
//
|
|
|
|
// Abstract: Method to set the address to utilize for communicating
|
|
|
|
// with the server via TCP sockets.
|
|
|
|
//
|
|
|
|
// Note: The service needs to be initialized before calling this procedure.
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int retStatus = -1;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerSetInAddress- Start\n", 0);
|
|
|
|
|
|
|
|
// Verify the input parameters
|
|
|
|
if (listenPort == 0)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerSetInAddress- Invalid input parameter\n", 0);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure that we have been initialized
|
|
|
|
if (svcInitialized)
|
|
|
|
{
|
|
|
|
// Make sure that the address has not already been set.
|
|
|
|
if (serverAddressSet == false)
|
|
|
|
{
|
|
|
|
// Save the listen port number
|
|
|
|
listenPortNumber = listenPort;
|
|
|
|
|
|
|
|
// Remember this
|
|
|
|
serverAddressSet = true;
|
|
|
|
use_AF_INET = true;
|
|
|
|
use_PF_UNIX = false;
|
|
|
|
|
|
|
|
// Success
|
|
|
|
retStatus = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerSetInAddress- Already set\n", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerSetInAddress- Service not yet initialized\n", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerSetInAddress- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
|
|
|
|
} /*-- IpcServerSetInAddress() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
int
|
|
|
|
IpcServerInit(
|
|
|
|
IN char *pName,
|
|
|
|
IN int debugLevel,
|
|
|
|
IN bool useSyslog)
|
|
|
|
//
|
|
|
|
// Arguments In: pName - Pointer to string containing the name that the
|
|
|
|
// calling application wants associated with the
|
|
|
|
// debug logs emitted by the library.
|
|
|
|
//
|
|
|
|
// debugLevel - The level that the library should use for
|
|
|
|
// determining what information should be logged
|
|
|
|
// for debugging purposes. 0 being the lowest
|
|
|
|
// level.
|
|
|
|
//
|
|
|
|
// useSyslog - Set to TRUE to log debug statements using Syslog,
|
|
|
|
// else debugs are log to stderr.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: 0 == Success
|
|
|
|
// -1 == Failure
|
|
|
|
//
|
|
|
|
// Abstract: Method to initialize the IPC infrastructure for process.
|
|
|
|
//
|
|
|
|
// Note: It is necessary to call the start procedure to start
|
|
|
|
// servicing requests.
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
int retStatus = -1;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerInit- Start\n", 0);
|
|
|
|
|
|
|
|
// Check input parameters
|
|
|
|
if (pAppName == NULL)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerInit- Invalid parameter\n", 0);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save a copy of the application name
|
|
|
|
pAppName = new char[strlen(pName) + 1];
|
|
|
|
if (pAppName == NULL)
|
|
|
|
{
|
|
|
|
DbgTrace(0, "IpcServerInit- Memory allocation failure\n", 0);
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
strcpy(pAppName, pName);
|
|
|
|
|
|
|
|
// Save the rest of the debug settings
|
|
|
|
DebugLevel = debugLevel;
|
|
|
|
UseSyslog = useSyslog;
|
|
|
|
|
|
|
|
// Set to ignore SIGPIPE signals
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
|
|
// Initialize our mutexes
|
|
|
|
pthread_mutex_init(&serverMutex, NULL);
|
|
|
|
pthread_mutex_init(&interlockedMutex, NULL);
|
|
|
|
|
|
|
|
// Success
|
|
|
|
svcInitialized = true;
|
|
|
|
retStatus = 0;
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerInit- End, retStatus = %08X\n", retStatus);
|
|
|
|
|
|
|
|
return retStatus;
|
|
|
|
|
|
|
|
} /*-- IpcServerInit() --*/
|
|
|
|
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
|
|
extern "C"
|
|
|
|
void
|
|
|
|
IpcServerShutdown(void)
|
|
|
|
//
|
|
|
|
// Arguments In: None.
|
|
|
|
//
|
|
|
|
// Arguments Out: None.
|
|
|
|
//
|
|
|
|
// Returns: Nothing.
|
|
|
|
//
|
|
|
|
// Abstract: Method to shutdown the IPC service.
|
|
|
|
//
|
|
|
|
// Note:
|
|
|
|
//
|
2006-09-01 07:37:43 +02:00
|
|
|
// L2
|
2006-09-01 01:05:25 +02:00
|
|
|
//=======================================================================--
|
|
|
|
{
|
|
|
|
DbgTrace(1, "IpcServerShutdown- Start\n", 0);
|
|
|
|
|
|
|
|
// Verify that we have been initialized
|
|
|
|
if (svcInitialized)
|
|
|
|
{
|
|
|
|
// We are being asked to terminate
|
|
|
|
terminating = true;
|
|
|
|
|
|
|
|
// Abort all pending requests
|
|
|
|
AbortPendingRequests();
|
|
|
|
|
|
|
|
// Awaken any suspended server threads
|
|
|
|
AwakenSuspendedServerThreads();
|
|
|
|
|
|
|
|
// Wait for all of the active requests to complete
|
|
|
|
while (numActiveRequests)
|
|
|
|
sleep(1);
|
|
|
|
|
|
|
|
// Close the listen socket if not already closed. This will
|
|
|
|
// cause the ServiceConnectionsThread to clean things up and
|
|
|
|
// shutdown.
|
|
|
|
if (listenSocket != INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
// Close the socket
|
|
|
|
closesocket(listenSocket);
|
|
|
|
listenSocket = INVALID_SOCKET;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Forget about having being initialized
|
|
|
|
svcInitialized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free the AppName string if necessary
|
|
|
|
if (pAppName != unInitialized)
|
|
|
|
{
|
|
|
|
delete[] pAppName;
|
|
|
|
pAppName = unInitialized;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Forget about some things
|
|
|
|
serverAddressSet = false;
|
|
|
|
svcInitialized = false;
|
|
|
|
|
|
|
|
DbgTrace(1, "IpcServerShutdown- End\n", 0);
|
|
|
|
|
|
|
|
} /*-- IpcServerShutdown() --*/
|
|
|
|
|
|
|
|
//=========================================================================
|
|
|
|
//=========================================================================
|