urpConnect update git-svn-id: svn://10.0.0.236/trunk@99146 18797224-902f-48f8-a5cc-f745e15eee43
547 lines
16 KiB
C++
547 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Sun Microsystems,
|
|
* Inc. Portions created by Sun are
|
|
* Copyright (C) 1999 Sun Microsystems, Inc. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Sergey Lunegov <lsv@sparc.spb.su>
|
|
*/
|
|
|
|
#include "prmem.h"
|
|
#include "nsIInterfaceInfo.h"
|
|
#include "nsIInterfaceInfoManager.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "xptcall.h"
|
|
#include "nsCRT.h"
|
|
#include "urpManager.h"
|
|
#include <unistd.h>
|
|
#include "urpStub.h"
|
|
#include "urpMarshalToolkit.h"
|
|
#include "urpLog.h"
|
|
|
|
|
|
#include "nsIModule.h"
|
|
|
|
|
|
class threadHashKey : public nsHashKey {
|
|
public:
|
|
threadHashKey(bcTID thrdID) : threadID(thrdID) {}
|
|
|
|
virtual PRUint32 HashCode(void) const
|
|
{
|
|
return PRUint32(threadID);
|
|
}
|
|
|
|
virtual PRBool Equals(const nsHashKey *aKey) const
|
|
{
|
|
return ((threadHashKey*)aKey)->threadID == threadID;
|
|
}
|
|
|
|
virtual nsHashKey *Clone(void) const
|
|
{
|
|
return new threadHashKey(threadID);
|
|
}
|
|
|
|
private:
|
|
bcTID threadID;
|
|
};
|
|
|
|
struct localThreadArg {
|
|
urpManager *mgr;
|
|
urpConnection *conn;
|
|
PRBool isClnt;
|
|
localThreadArg( urpManager *mgr, urpConnection *conn, PRBool ic ) {
|
|
this->mgr = mgr;
|
|
this->conn = conn;
|
|
this->isClnt = ic;
|
|
}
|
|
};
|
|
|
|
struct sendThreadArg {
|
|
urpManager* man;
|
|
char header;
|
|
urpPacket* message;
|
|
bcIID iid;
|
|
bcOID oid;
|
|
bcTID tid;
|
|
PRUint16 methodId;
|
|
urpConnection* connection;
|
|
sendThreadArg(urpManager* m, char header, urpPacket* message, bcIID iid,
|
|
bcOID oid, bcTID tid, PRUint16 methodId,
|
|
urpConnection* conn) {
|
|
this->man = m;
|
|
this->header = header;
|
|
this->message = message;
|
|
this->iid = iid;
|
|
this->oid = oid;
|
|
this->tid = tid;
|
|
this->methodId = methodId;
|
|
this->connection = conn;
|
|
}
|
|
};
|
|
|
|
struct monitCall {
|
|
PRCList* stack;
|
|
/*
|
|
PRMonitor *mon;
|
|
bcICall* call;
|
|
*/
|
|
urpPacket* mess;
|
|
char header;
|
|
bcIID iid;
|
|
bcOID oid;
|
|
bcTID tid;
|
|
bcMID mid;
|
|
int request;
|
|
monitCall(PRCList* stack, urpPacket* mes, char h) {
|
|
this->stack = stack;
|
|
this->mess = mes;
|
|
this->header = h;
|
|
this->request = 0;
|
|
}
|
|
};
|
|
|
|
void thread_start( void *arg )
|
|
{
|
|
urpManager *manager = ((localThreadArg *)arg)->mgr;
|
|
urpConnection *connection = ((localThreadArg *)arg)->conn;
|
|
PRBool ic = ((localThreadArg *)arg)->isClnt;
|
|
nsresult rv = manager->ReadMessage( connection, ic );
|
|
}
|
|
|
|
void send_thread_start (void * arg) {
|
|
urpManager *manager = ((sendThreadArg *)arg)->man;
|
|
char header = ((sendThreadArg *)arg)->header;
|
|
urpPacket* mes = ((sendThreadArg *)arg)->message;
|
|
bcIID iid = ((sendThreadArg *)arg)->iid;
|
|
bcOID oid = ((sendThreadArg *)arg)->oid;
|
|
bcTID tid = ((sendThreadArg *)arg)->tid;
|
|
PRUint16 methodId = ((sendThreadArg *)arg)->methodId;
|
|
urpConnection* conn = ((sendThreadArg *)arg)->connection;
|
|
nsresult rv = manager->ReadLongRequest(header, mes, iid, oid,
|
|
tid, methodId, conn);
|
|
//printf("just run test\n");
|
|
}
|
|
|
|
urpManager::urpManager(PRBool IsClient, bcIORB *orb, urpConnection* conn) {
|
|
broker = orb;
|
|
monitTable = new nsHashtable(20);
|
|
if(IsClient) {
|
|
threadTable = nsnull;
|
|
localThreadArg *arg = new localThreadArg( this, conn, PR_TRUE );
|
|
PRThread *thr = PR_CreateThread( PR_USER_THREAD,
|
|
thread_start,
|
|
arg,
|
|
PR_PRIORITY_NORMAL,
|
|
PR_LOCAL_THREAD,
|
|
PR_UNJOINABLE_THREAD,
|
|
0);
|
|
if(thr == nsnull) {
|
|
printf("Error couldn't run listener\n");
|
|
// exit(-1);
|
|
}
|
|
} else
|
|
threadTable = new nsHashtable(20);
|
|
}
|
|
|
|
|
|
urpManager::~urpManager() {
|
|
if(monitTable)
|
|
delete monitTable;
|
|
}
|
|
|
|
|
|
|
|
void urpManager::SendUrpRequest(bcOID oid, bcIID iid,
|
|
PRUint16 methodIndex,
|
|
nsIInterfaceInfo* interfaceInfo,
|
|
bcICall *call,
|
|
PRUint32 paramCount, const nsXPTMethodInfo* info,
|
|
urpConnection* connection) {
|
|
PRLogModuleInfo *log = urpLog::GetLog();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("this is method sendUrpRequest and mid is %x\n",methodIndex));
|
|
long size = 0;
|
|
long messagesCount = 0;
|
|
urpPacket* message = new urpPacket();
|
|
|
|
char header = 0x0;
|
|
char bigHeader = 0x0;
|
|
char synchron = 0x1;
|
|
char mustReply = 0x1;
|
|
|
|
if(1) { //there should be checking on whether oid is the new one
|
|
header |= NEWOID;
|
|
bigHeader = 0x1;
|
|
}
|
|
|
|
if(1) { //there should be checking on whether type is the new one
|
|
header |= NEWTYPE;
|
|
bigHeader = 0x1;
|
|
}
|
|
|
|
if(1) { //there should be checking on whether threadid is the new one
|
|
header |= NEWTID;
|
|
bigHeader = 0x1;
|
|
}
|
|
|
|
if(bigHeader) {
|
|
header |= BIG_HEADER;
|
|
header |= 0x80;
|
|
header |= REQUEST;
|
|
header |= 0;
|
|
|
|
if(methodIndex > 255)
|
|
header |= LONGMETHODID;
|
|
|
|
message->WriteByte(header);
|
|
|
|
if(methodIndex > 255)
|
|
message->WriteShort(methodIndex);
|
|
else
|
|
message->WriteByte((char)methodIndex);
|
|
}
|
|
|
|
urpMarshalToolkit* mt = new urpMarshalToolkit(PR_TRUE);
|
|
mt->WriteType(iid, message);
|
|
mt->WriteOid(oid, message);
|
|
bcTID thrID;
|
|
bcTID* thr;
|
|
if(threadTable) {
|
|
thrID = (bcTID)PR_GetCurrentThread();
|
|
threadHashKey thrHK(thrID);
|
|
thr = (bcTID*)threadTable->Get(&thrHK);
|
|
if(thr)
|
|
thrID = *(bcTID*)thr;
|
|
else {
|
|
printf("Error with threads in SendUrpRequest\n");
|
|
// exit(-1);
|
|
}
|
|
} else
|
|
thrID = (bcTID)PR_GetCurrentThread();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("OID is written %ld %ld\n", oid, thrID));
|
|
mt->WriteThreadID(thrID, message);
|
|
broker = call->GetORB();
|
|
mt->WriteParams(call, paramCount, info, interfaceInfo, message, methodIndex);
|
|
delete mt;
|
|
connection->Write(message);
|
|
delete message;
|
|
}
|
|
|
|
void urpManager::TransformMethodIDAndIID() {
|
|
PRLogModuleInfo *log = urpLog::GetLog();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("this is method transformMethodIDAndIID\n"));
|
|
}
|
|
|
|
nsresult
|
|
urpManager::ReadReply(urpPacket* message, char header,
|
|
bcICall* call, PRUint32 paramCount,
|
|
const nsXPTMethodInfo *info,
|
|
nsIInterfaceInfo *interfaceInfo, PRUint16 methodIndex,
|
|
urpConnection* conn) {
|
|
nsresult rv = NS_OK;
|
|
PRLogModuleInfo *log = urpLog::GetLog();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("this is method readReply\n"));
|
|
if(methodIndex != 1 && methodIndex != 2) {
|
|
urpMarshalToolkit* mt = new urpMarshalToolkit(PR_TRUE);
|
|
rv = mt->ReadParams(paramCount, info, message, interfaceInfo, methodIndex, call, broker, this, conn);
|
|
delete mt;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
urpManager::ReadMessage(urpConnection* conn, PRBool isClient) {
|
|
nsresult rv = NS_OK;
|
|
PRBool inserted = PR_FALSE;
|
|
bcTID tid;
|
|
PRThread *thr;
|
|
sendThreadArg *arg = (sendThreadArg *)PR_Malloc(sizeof(sendThreadArg));
|
|
while(conn->GetStatus() == urpSuccess) {
|
|
urpPacket* message = conn->Read();
|
|
char header = message->ReadByte();
|
|
if((header & BIG_HEADER) != 0) { // full header?
|
|
if((header & REQUEST) != 0) { // a request ?
|
|
bcIID iid;
|
|
bcOID oid;
|
|
PRUint16 methodId;
|
|
if((header & LONGMETHODID) != 0) // usigned short ?
|
|
methodId = message->ReadShort();
|
|
else
|
|
methodId = message->ReadByte();
|
|
|
|
urpMarshalToolkit* mt = new urpMarshalToolkit(PR_FALSE);
|
|
if((header & NEWTYPE) != 0)
|
|
iid = mt->ReadType(message);
|
|
|
|
if((header & NEWOID) != 0) // new oid?
|
|
oid = mt->ReadOid(message);
|
|
|
|
if((header & NEWTID) != 0) // new thread id ?
|
|
tid = mt->ReadThreadID(message);
|
|
|
|
delete mt;
|
|
|
|
threadHashKey thrHK(tid);
|
|
monitCall* mc = (monitCall*)monitTable->Get(&thrHK);
|
|
if(mc != nsnull) {
|
|
mc->mess = message;
|
|
mc->header = header;
|
|
mc->iid = iid;
|
|
mc->oid = oid;
|
|
mc->tid = tid;
|
|
mc->mid = methodId;
|
|
mc->request = 1;
|
|
PRMonitor* mon = (PRMonitor*)PR_LIST_HEAD(mc->stack);
|
|
PR_EnterMonitor(mon);
|
|
PR_Notify(mon);
|
|
PR_ExitMonitor(mon);
|
|
} else {
|
|
arg->man = this;
|
|
arg->header = header;
|
|
arg->message = message;
|
|
arg->iid = iid;
|
|
arg->oid = oid;
|
|
arg->tid = tid;
|
|
arg->methodId = methodId;
|
|
arg->connection = conn;
|
|
/*
|
|
sendThreadArg *arg = new sendThreadArg( this, header,
|
|
message, iid, oid, tid, methodId, conn);
|
|
*/
|
|
thr = PR_CreateThread( PR_USER_THREAD,
|
|
send_thread_start,
|
|
arg,
|
|
PR_PRIORITY_NORMAL,
|
|
PR_LOCAL_THREAD,
|
|
PR_UNJOINABLE_THREAD,
|
|
0);
|
|
//ReadLongRequest(header, message, iid, oid, tid, methodId, conn);
|
|
}
|
|
} else { // a reply
|
|
bcIID iid; bcOID oid; bcMID mid;
|
|
|
|
urpMarshalToolkit* mt = new urpMarshalToolkit(PR_TRUE);
|
|
if((header & NEWTID) != 0) { // new thread id ?
|
|
printf("new threadID\n");
|
|
tid = mt->ReadThreadID(message);
|
|
}
|
|
else
|
|
printf("old threadID\n");
|
|
delete mt;
|
|
threadHashKey thrHK(tid);
|
|
monitCall* mc = (monitCall*)monitTable->Get(&thrHK);
|
|
mc->mess = message;
|
|
mc->header = header;
|
|
mc->request = 0;
|
|
/*
|
|
mc->call->GetParams(&iid, &oid, &mid);
|
|
nsIInterfaceInfo *interfaceInfo;
|
|
nsIInterfaceInfoManager* iimgr;
|
|
if( (iimgr = XPTI_GetInterfaceInfoManager()) ) {
|
|
if (NS_FAILED(iimgr->GetInfoForIID(&iid, &interfaceInfo))) {
|
|
printf("Error in ReadMessage\n");
|
|
return NS_ERROR_FAILURE; //nb exception handling
|
|
}
|
|
NS_RELEASE(iimgr);
|
|
} else {
|
|
printf("Error in ReadMessage in second place\n");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsXPTMethodInfo* info;
|
|
interfaceInfo->GetMethodInfo(mid, (const nsXPTMethodInfo **)&info);
|
|
PRUint32 paramCount = info->GetParamCount();
|
|
ReadReply(message, header, mc->call, paramCount,
|
|
info, interfaceInfo, mid, conn);
|
|
*/
|
|
PRMonitor* mon = (PRMonitor*)PR_LIST_HEAD(mc->stack);
|
|
PR_EnterMonitor(mon);
|
|
PR_Notify(mon);
|
|
PR_ExitMonitor(mon);
|
|
}
|
|
}
|
|
else { // only a short request header
|
|
// rv = ReadShortRequest(header, message);
|
|
break;
|
|
}
|
|
}
|
|
PR_Free(arg);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
urpManager::ReadShortRequest(char header, urpPacket* message) {
|
|
nsresult rv = NS_OK;
|
|
bcTID tid = 0;
|
|
printf("null implementation of readShortRequest\n");
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
urpManager::SendReply(bcTID tid, bcICall* call, PRUint32 paramCount,
|
|
const nsXPTMethodInfo* info,
|
|
nsIInterfaceInfo *interfaceInfo, PRUint16 methodIndex,
|
|
urpConnection* connection) {
|
|
nsresult rv = NS_OK;
|
|
char header = (char)BIG_HEADER;
|
|
header |= NEWTID;
|
|
urpPacket* message = new urpPacket();
|
|
message->WriteByte(header);
|
|
urpMarshalToolkit* mt = new urpMarshalToolkit(PR_FALSE);
|
|
mt->WriteThreadID(tid, message);
|
|
if(methodIndex != 1 && methodIndex != 2)
|
|
rv = mt->WriteParams(call, paramCount, info, interfaceInfo, message, methodIndex);
|
|
delete mt;
|
|
if(NS_FAILED(rv)) return rv;
|
|
connection->Write(message);
|
|
delete message;
|
|
return rv;
|
|
}
|
|
|
|
|
|
nsresult
|
|
urpManager::ReadLongRequest(char header, urpPacket* message,
|
|
bcIID iid, bcOID oid, bcTID tid,
|
|
PRUint16 methodId, urpConnection* conn) {
|
|
nsresult rv = NS_OK;
|
|
|
|
if(threadTable != nsnull) {
|
|
bcTID thrID = (bcTID)PR_GetCurrentThread();
|
|
threadHashKey thrHK(thrID);
|
|
bcTID* clientTID = (bcTID*)threadTable->Get(&thrHK);
|
|
if(clientTID) thrID = *clientTID;
|
|
if(clientTID) {
|
|
if(thrID != tid) {
|
|
printf("Error: threadIDs are not equal in ReadLongRequest\n");
|
|
// exit(-1);
|
|
}
|
|
} else
|
|
threadTable->Put(&thrHK, &tid);
|
|
}
|
|
|
|
urpMarshalToolkit* mt = new urpMarshalToolkit(PR_FALSE);
|
|
|
|
PRLogModuleInfo *log = urpLog::GetLog();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("method readLongRequest: tid %ld %ld\n",tid,oid));
|
|
char ignore_cache = ((header & IGNORECACHE) != 0); // do not use cache for this request?
|
|
|
|
char mustReply;
|
|
|
|
if((header & MOREFLAGS) != 0) {// is there an extended flags byte?
|
|
char exFlags = message->ReadByte();
|
|
|
|
mustReply = (exFlags & MUSTREPLY) != 0;
|
|
}
|
|
else {
|
|
mustReply = 0x1;
|
|
}
|
|
|
|
nsIInterfaceInfo *interfaceInfo;
|
|
nsIInterfaceInfoManager* iimgr;
|
|
if( (iimgr = XPTI_GetInterfaceInfoManager()) ) {
|
|
if (NS_FAILED(iimgr->GetInfoForIID(&iid, &interfaceInfo))) {
|
|
delete mt;
|
|
return NS_ERROR_FAILURE; //nb exception handling
|
|
}
|
|
NS_RELEASE(iimgr);
|
|
} else {
|
|
delete mt;
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
/*
|
|
char* name;
|
|
interfaceInfo->GetName(&name);
|
|
printf("in handleRequest interface name is %s\n",name);
|
|
*/
|
|
nsXPTMethodInfo* info;
|
|
interfaceInfo->GetMethodInfo(methodId,(const nsXPTMethodInfo **)&info);
|
|
PRUint32 paramCount = info->GetParamCount();
|
|
bcICall *call = broker->CreateCall(&iid, &oid, methodId);
|
|
mt->ReadParams(paramCount, info, message, interfaceInfo, methodId, call, broker, this, conn);
|
|
delete mt;
|
|
delete message;
|
|
//nb return value; excepion handling
|
|
broker->SendReceive(call);
|
|
rv = SendReply(tid, call, paramCount, info, interfaceInfo,
|
|
methodId, conn);
|
|
// delete call;
|
|
// NS_RELEASE(interfaceInfo);
|
|
return rv;
|
|
}
|
|
|
|
nsresult
|
|
urpManager::SetCall(bcICall* call, PRMonitor *m, bcTID thrID) {
|
|
monitCall* mc;
|
|
// = new monitCall(m, call, nsnull, 0);
|
|
PRLogModuleInfo *log = urpLog::GetLog();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("method SetCall %p %p %p %ld\n",call, m, this, thrID));
|
|
threadHashKey thrHK(thrID);
|
|
if(!(mc = (monitCall*)monitTable->Get(&thrHK))) {
|
|
PR_INIT_CLIST((PRCList*)m);
|
|
mc = new monitCall((PRCList*)m, nsnull, 0);
|
|
monitTable->Put(&thrHK, mc);
|
|
} else {
|
|
PR_INSERT_LINK((PRCList*)m, mc->stack);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
urpManager::RemoveCall(forReply* fR, bcTID thrID) {
|
|
PRLogModuleInfo *log = urpLog::GetLog();
|
|
PR_LOG(log, PR_LOG_DEBUG, ("method RemoveCall\n"));
|
|
threadHashKey thrHK(thrID);
|
|
monitCall* mc = (monitCall*)monitTable->Get(&thrHK);
|
|
fR->mess= mc->mess;
|
|
fR->header = mc->header;
|
|
if(!mc->request) {
|
|
mc = (monitCall*)monitTable->Get(&thrHK);
|
|
PR_REMOVE_LINK(mc->stack);
|
|
if(PR_CLIST_IS_EMPTY(mc->stack)) {
|
|
mc = (monitCall*)monitTable->Remove(&thrHK);
|
|
delete mc;
|
|
} else {
|
|
PR_LOG(log, PR_LOG_DEBUG, ("It is not error\n"));
|
|
}
|
|
} else {
|
|
fR->iid = mc->iid;
|
|
fR->oid = mc->oid;
|
|
fR->tid = mc->tid;
|
|
fR->methodId = mc->mid;
|
|
fR->request = mc->request;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
bcTID
|
|
urpManager::GetThread() {
|
|
bcTID thrID;
|
|
bcTID* thr;
|
|
if(threadTable) {
|
|
thrID = (bcTID)PR_GetCurrentThread();
|
|
threadHashKey thrHK(thrID);
|
|
thr = (bcTID*)threadTable->Get(&thrHK);
|
|
if(thr)
|
|
thrID = *(bcTID*)thr;
|
|
else {
|
|
printf("Error with threads in SendUrpRequest\n");
|
|
// exit(-1);
|
|
}
|
|
} else
|
|
thrID = (bcTID)PR_GetCurrentThread();
|
|
return thrID;
|
|
}
|