Allow InProcessExampleBrowser to use a malloc allocated memory block, instead of system shared memory.

Make shared memory client/server a bit more robust, in case the server is terminated early.
This commit is contained in:
erwincoumans
2016-03-10 14:36:46 -08:00
parent 40a9b8cea0
commit efbb1edecc
19 changed files with 186 additions and 23 deletions

View File

@@ -0,0 +1,49 @@
#include "InProcessMemory.h"
#include "LinearMath/btHashMap.h"
struct InProcessMemoryInternalData
{
btHashMap<btHashInt, void*> m_memoryPointers;
};
InProcessMemory::InProcessMemory()
{
m_data = new InProcessMemoryInternalData;
}
InProcessMemory::~InProcessMemory()
{
for (int i=0;i<m_data->m_memoryPointers.size();i++)
{
void** ptrptr = m_data->m_memoryPointers.getAtIndex(i);
if (ptrptr)
{
void* ptr = *ptrptr;
free(ptr);
}
}
delete m_data;
}
void* InProcessMemory::allocateSharedMemory(int key, int size, bool allowCreation)
{
void** ptrptr = m_data->m_memoryPointers[key];
if (ptrptr)
{
return *ptrptr;
}
void* ptr = malloc(size);
m_data->m_memoryPointers.insert(key,ptr);
return ptr;
}
void InProcessMemory::releaseSharedMemory(int /*key*/, int /*size*/)
{
//we don't release the memory here, but in the destructor instead,
//so multiple users could 'share' the memory given some key
}

View File

@@ -0,0 +1,19 @@
#ifndef IN_PROCESS_MEMORY_H
#define IN_PROCESS_MEMORY_H
#include "SharedMemoryInterface.h"
class InProcessMemory : public SharedMemoryInterface
{
struct InProcessMemoryInternalData* m_data;
public:
InProcessMemory();
virtual ~InProcessMemory();
virtual void* allocateSharedMemory(int key, int size, bool allowCreation);
virtual void releaseSharedMemory(int key, int size);
};
#endif

View File

@@ -72,7 +72,7 @@ b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
b3Assert(cl->canSubmitCommand());
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type = CMD_SEND_PHYSICS_SIMULATION_PARAMETERS;
@@ -445,9 +445,12 @@ void b3DisconnectSharedMemory(b3PhysicsClientHandle physClient)
b3SharedMemoryStatusHandle b3ProcessServerStatus(b3PhysicsClientHandle physClient)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
const SharedMemoryStatus* stat = cl->processServerStatus();
return (b3SharedMemoryStatusHandle) stat;
if (cl && cl->isConnected())
{
const SharedMemoryStatus* stat = cl->processServerStatus();
return (b3SharedMemoryStatusHandle) stat;
}
return 0;
}
@@ -461,7 +464,7 @@ int b3GetStatusType(b3SharedMemoryStatusHandle statusHandle)
{
return status->m_type;
}
return 0;
return CMD_INVALID_STATUS;
}
int b3GetStatusBodyIndex(b3SharedMemoryStatusHandle statusHandle)

View File

@@ -23,6 +23,7 @@ struct BodyJointInfoCache
struct PhysicsClientSharedMemoryInternalData {
SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory;
SharedMemoryBlock* m_testBlock1;
btHashMap<btHashInt,BodyJointInfoCache*> m_bodyJointMap;
@@ -43,6 +44,7 @@ struct PhysicsClientSharedMemoryInternalData {
PhysicsClientSharedMemoryInternalData()
: m_sharedMemory(0),
m_ownsSharedMemory(false),
m_testBlock1(0),
m_counter(0),
m_serverLoadUrdfOK(false),
@@ -95,23 +97,40 @@ PhysicsClientSharedMemory::PhysicsClientSharedMemory()
#else
m_data->m_sharedMemory = new PosixSharedMemory();
#endif
m_data->m_ownsSharedMemory = true;
}
PhysicsClientSharedMemory::~PhysicsClientSharedMemory() {
if (m_data->m_isConnected) {
disconnectSharedMemory();
}
delete m_data->m_sharedMemory;
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
delete m_data;
}
void PhysicsClientSharedMemory::setSharedMemoryKey(int key) { m_data->m_sharedMemoryKey = key; }
void PhysicsClientSharedMemory::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
{
if (m_data->m_sharedMemory && m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_ownsSharedMemory = false;
m_data->m_sharedMemory = sharedMem;
}
void PhysicsClientSharedMemory::disconnectSharedMemory() {
if (m_data->m_isConnected) {
if (m_data->m_isConnected && m_data->m_sharedMemory) {
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
m_data->m_isConnected = false;
}
m_data->m_isConnected = false;
}
bool PhysicsClientSharedMemory::isConnected() const { return m_data->m_isConnected; }
@@ -146,13 +165,20 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
SharedMemoryStatus* stat = 0;
if (!m_data->m_testBlock1) {
return 0;
m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_data->m_lastServerStatus;
}
if (!m_data->m_waitingForServer) {
return 0;
}
if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER)
{
m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_data->m_lastServerStatus;
}
if (m_data->m_testBlock1->m_numServerCommands >
m_data->m_testBlock1->m_numProcessedServerCommands) {
btAssert(m_data->m_testBlock1->m_numServerCommands ==
@@ -446,7 +472,6 @@ bool PhysicsClientSharedMemory::submitClientCommand(const SharedMemoryCommand& c
/// at the moment we allow a maximum of 1 outstanding command, so we check for this
// once the server processed the command and returns a status, we clear the flag
// "m_data->m_waitingForServer" and allow submitting the next command
btAssert(!m_data->m_waitingForServer);
if (!m_data->m_waitingForServer) {
if (&m_data->m_testBlock1->m_clientCommands[0] != &command) {

View File

@@ -10,6 +10,8 @@ class PhysicsClientSharedMemory : public PhysicsClient {
struct PhysicsClientSharedMemoryInternalData* m_data;
protected:
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
public:
PhysicsClientSharedMemory();
virtual ~PhysicsClientSharedMemory();

View File

@@ -22,7 +22,7 @@ class PhysicsServerExample : public SharedMemoryCommon
public:
PhysicsServerExample(GUIHelperInterface* helper);
PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem=0);
virtual ~PhysicsServerExample();
@@ -133,8 +133,9 @@ public:
};
PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper)
PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem)
:SharedMemoryCommon(helper),
m_physicsServer(sharedMem),
m_wantsShutdown(false),
m_isConnected(false),
m_replay(false)
@@ -287,7 +288,7 @@ extern int gSharedMemoryKey;
class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOptions& options)
{
PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper);
PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper, options.m_sharedMem);
if (gSharedMemoryKey>=0)
{
example->setSharedMemoryKey(gSharedMemoryKey);

View File

@@ -23,6 +23,8 @@ struct PhysicsServerSharedMemoryInternalData
SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory;
SharedMemoryBlock* m_testBlock1;
int m_sharedMemoryKey;
bool m_isConnected;
@@ -31,6 +33,7 @@ struct PhysicsServerSharedMemoryInternalData
PhysicsServerSharedMemoryInternalData()
:m_sharedMemory(0),
m_ownsSharedMemory(false),
m_testBlock1(0),
m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_isConnected(false),
@@ -57,16 +60,23 @@ struct PhysicsServerSharedMemoryInternalData
};
PhysicsServerSharedMemory::PhysicsServerSharedMemory()
PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* sharedMem)
{
m_data = new PhysicsServerSharedMemoryInternalData();
if (sharedMem)
{
m_data->m_sharedMemory = sharedMem;
m_data->m_ownsSharedMemory = false;
} else
{
#ifdef _WIN32
m_data->m_sharedMemory = new Win32SharedMemoryServer();
#else
m_data->m_sharedMemory = new PosixSharedMemory();
#endif
m_data->m_ownsSharedMemory = true;
}
m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
@@ -176,7 +186,10 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe
{
b3Printf("m_sharedMemory\n");
}
delete m_data->m_sharedMemory;
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_sharedMemory = 0;
m_data->m_testBlock1 = 0;
}
@@ -209,7 +222,10 @@ void PhysicsServerSharedMemory::releaseSharedMemory()
{
b3Printf("m_sharedMemory\n");
}
delete m_data->m_sharedMemory;
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_sharedMemory = 0;
m_data->m_testBlock1 = 0;
}

View File

@@ -14,7 +14,7 @@ protected:
public:
PhysicsServerSharedMemory();
PhysicsServerSharedMemory(class SharedMemoryInterface* sharedMem=0);
virtual ~PhysicsServerSharedMemory();
virtual void setSharedMemoryKey(int key);

View File

@@ -21,10 +21,14 @@ public:
newargv[argc] = t0;
newargv[argc+1] = t1;
m_data = btCreateInProcessExampleBrowser(newargc,newargv);
SharedMemoryInterface* shMem = btGetSharedMemoryInterface(m_data);
setSharedMemoryInterface(shMem);
}
virtual ~InProcessPhysicsClientSharedMemory()
{
setSharedMemoryInterface(0);
btShutDownExampleBrowser(m_data);
}

View File

@@ -30,7 +30,6 @@ enum EnumSharedMemoryServerStatus
{
CMD_SHARED_MEMORY_NOT_INITIALIZED=0,
CMD_WAITING_FOR_CLIENT_COMMAND,
//CMD_CLIENT_COMMAND_COMPLETED is a generic 'completed' status that doesn't need special handling on the client
CMD_CLIENT_COMMAND_COMPLETED,
//the server will skip unknown command and report a status 'CMD_UNKNOWN_COMMAND_FLUSHED'
@@ -50,6 +49,7 @@ enum EnumSharedMemoryServerStatus
CMD_DESIRED_STATE_RECEIVED_COMPLETED,
CMD_STEP_FORWARD_SIMULATION_COMPLETED,
CMD_RESET_SIMULATION_COMPLETED,
CMD_INVALID_STATUS,
CMD_MAX_SERVER_COMMANDS
};

View File

@@ -29,6 +29,7 @@ files {
"PhysicsServer.cpp",
"PosixSharedMemory.cpp",
"Win32SharedMemory.cpp",
"InProcessMemory.cpp",
"PhysicsDirect.cpp",
"PhysicsDirect.h",
"PhysicsDirectC_API.cpp",