static void BindDCOMServer()
{
+ bool mutexDeclared = false;
Class _class;
for(_class = privateModule.classes.first; _class; _class = _class.next)
{
break;
if(method)
{
+ if(!mutexDeclared)
+ {
+ DeclareClass(FindClass("ecere::sys::Mutex"), "__ecereClass___ecereNameSpace__ecere__sys__Mutex");
+ DeclareMethod(
+ eClass_FindMethod(
+ eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Wait", privateModule),
+ "__ecereMethod___ecereNameSpace__ecere__sys__Mutex_Wait");
+ DeclareMethod(
+ eClass_FindMethod(
+ eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Release", privateModule),
+ "__ecereMethod___ecereNameSpace__ecere__sys__Mutex_Release");
+ mutexDeclared = true;
+ }
+
f.Printf("\n");
if(!method.dataType)
method.dataType = ProcessTypeString(method.dataTypeString, false);
f.Printf(" = 0");
f.Printf(";\n\n");
}
+
+ f.Printf(" __ecereMethod___ecereNameSpace__ecere__sys__Mutex_Wait(__ecereObject.mutex);\n");
+
//f.Printf(" incref this;\n");
for(param = method.dataType.params.first; param; param = param.next)
{
DeclareMethod(
eClass_FindMethod(
eSystem_FindClass(privateModule, "ecere::net::DCOMServerObject"), "CallVirtualMethod", privateModule),
- "__ecereMethod___ecereNameSpace__ecere__net__DCOMServerObject_CallVirutalMethod");
+ "__ecereMethod___ecereNameSpace__ecere__net__DCOMServerObject_CallVirtualMethod");
- f.Printf(" if(__ecereObject.CallVirtualMethod(%d))\n", vid - _class.base.vTblSize);
+ // Check if this method needs to return anything (hasReturnValue)
+ {
+ bool hasReturnValue = false;
+ for(param = method.dataType.params.first; param; param = param.next)
+ {
+ if(param.kind == classType && ((param._class && param._class.registered && param._class.registered.type == structClass) || !strcmp(param._class.string, "String")) && !param.constant)
+ {
+ hasReturnValue = true;
+ break;
+ }
+ }
+ f.Printf(" if(__ecereObject.CallVirtualMethod(%d, %s))\n", vid - _class.base.vTblSize,
+ hasReturnValue ? "true" : "false");
+ }
f.Printf(" {\n");
for(param = method.dataType.params.first; param; param = param.next)
{
f.Printf(");\n");
f.Printf(" __ecereObject.virtualsBuffer.Free();\n");
+ f.Printf(" __ecereMethod___ecereNameSpace__ecere__sys__Mutex_Release(__ecereObject.mutex);\n");
//f.Printf(" delete this;\n");
if(method.dataType.returnType.kind != voidType)
{
static class CallVirtualMethodPacket : DCOMPacket
{
int methodID;
+ bool hasReturnValue;
unsigned int argsSize;
byte args[1];
};
virtual void CallMethod(unsigned int __ecereMethodID, SerialBuffer __ecereBuffer);
- dllexport bool CallVirtualMethod(unsigned int methodID)
+ dllexport bool CallVirtualMethod(unsigned int methodID, bool hasReturnValue)
{
bool reentrant = !answered;
- guiApp.Unlock();
+
if(serverSocket && serverSocket.connected)
{
unsigned int size = (uint)&((CallVirtualMethodPacket)0).args + virtualsBuffer.size; // sizeof(class CallVirtualMethodPacket) + virtualsBuffer.size - 1;
CallVirtualMethodPacket packet = (CallVirtualMethodPacket)new0 byte[size];
+ guiApp.Unlock();
+
packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_CallVirtualMethod);
packet.size = size;
packet.methodID = htoled(methodID);
+ packet.hasReturnValue = hasReturnValue;
packet.argsSize = htoled(virtualsBuffer.size);
virtualsBuffer.ReadData(packet.args, virtualsBuffer.size);
answered = false;
serverSocket.SendPacket(packet);
delete packet;
+ mutex.Release();
+
while(serverSocket && !answered)
{
if(GetCurrentThreadID() == serverSocket.thread.id)
else
serverSocket.thread.semaphore.Wait();
}
+
+ // NOTE: There is a slight potential that a virtual method
+ // returning a value might have its virtualsBuffer modified
+ // before we manage to lock it...
+ guiApp.Lock();
+ mutex.Wait();
+
if(reentrant)
answered = false;
- guiApp.Lock();
return overridden == true;
}
- guiApp.Lock();
return false;
}
// private:
SerialBuffer buffer { };
SerialBuffer virtualsBuffer { };
bool answered, overridden;
+ Mutex mutex { };
answered = true;
};
MethodReturnedPacket packet;
unsigned int size;
- SerialBuffer buffer = object.buffer;
+ SerialBuffer buffer { };
buffer.WriteData(callMethod.args, callMethod.argsSize);
// TOFIX: Hardcoded VTBL ID
packet.size = size;
packet.argsSize = htoled(buffer.size);
buffer.ReadData(packet.args, buffer.size);
- buffer.Free();
+ delete buffer;
SendPacket(packet);
delete packet;
}
CallVirtualMethodPacket callMethod = (CallVirtualMethodPacket)p;
VirtualMethodReturnedPacket packet;
unsigned int size = (uint)&((VirtualMethodReturnedPacket)0).args; // sizeof(class VirtualMethodReturnedPacket);
- SerialBuffer buffer = virtualsBuffer;
+ SerialBuffer buffer { };
// TOFIX: Hardcoded VTBL ID
bool overridden = _vTbl[18 + callMethod.methodID] != _class._vTbl[18 + callMethod.methodID];
callMethod.argsSize = letohd(callMethod.argsSize);
+
+ if(!callMethod.hasReturnValue)
+ {
+ packet = (VirtualMethodReturnedPacket)new0 byte[size];
+ packet.overridden = overridden;
+ packet.objectID = objectID;
+ packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_VirtualMethodReturned);
+ packet.size = size;
+ packet.argsSize = 0;
+ SendPacket(packet);
+ }
+
if(overridden)
{
buffer.WriteData(callMethod.args, callMethod.argsSize);
+
// TOFIX: Hardcoded VTBL ID
_vTbl[17](this, callMethod.methodID, buffer);
size += buffer.size; // - 1;
}
- packet = (VirtualMethodReturnedPacket)new0 byte[size];
- packet.overridden = overridden;
- packet.objectID = objectID;
- packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_VirtualMethodReturned);
- packet.size = size;
- packet.argsSize = htoled(buffer.size);
- buffer.ReadData(packet.args, buffer.size);
- buffer.Free();
- SendPacket(packet);
+ if(callMethod.hasReturnValue)
+ {
+ packet = (VirtualMethodReturnedPacket)new0 byte[size];
+ packet.overridden = overridden;
+ packet.objectID = objectID;
+ packet.type = (DCOMPacketType)htoled((DCOMPacketType)dcom_VirtualMethodReturned);
+ packet.size = size;
+ packet.argsSize = htoled(buffer.size);
+ buffer.ReadData(packet.args, buffer.size);
+ SendPacket(packet);
+ }
+ delete buffer;
delete packet;
break;
}