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:
49
examples/SharedMemory/InProcessMemory.cpp
Normal file
49
examples/SharedMemory/InProcessMemory.cpp
Normal 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
|
||||
}
|
||||
19
examples/SharedMemory/InProcessMemory.h
Normal file
19
examples/SharedMemory/InProcessMemory.h
Normal 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
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -10,6 +10,8 @@ class PhysicsClientSharedMemory : public PhysicsClient {
|
||||
struct PhysicsClientSharedMemoryInternalData* m_data;
|
||||
|
||||
protected:
|
||||
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
|
||||
|
||||
public:
|
||||
PhysicsClientSharedMemory();
|
||||
virtual ~PhysicsClientSharedMemory();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ protected:
|
||||
|
||||
|
||||
public:
|
||||
PhysicsServerSharedMemory();
|
||||
PhysicsServerSharedMemory(class SharedMemoryInterface* sharedMem=0);
|
||||
virtual ~PhysicsServerSharedMemory();
|
||||
|
||||
virtual void setSharedMemoryKey(int key);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ files {
|
||||
"PhysicsServer.cpp",
|
||||
"PosixSharedMemory.cpp",
|
||||
"Win32SharedMemory.cpp",
|
||||
"InProcessMemory.cpp",
|
||||
"PhysicsDirect.cpp",
|
||||
"PhysicsDirect.h",
|
||||
"PhysicsDirectC_API.cpp",
|
||||
|
||||
Reference in New Issue
Block a user