diff --git a/examples/SharedMemory/PhysicsServerExample.cpp b/examples/SharedMemory/PhysicsServerExample.cpp index 9358f41a7..994312986 100644 --- a/examples/SharedMemory/PhysicsServerExample.cpp +++ b/examples/SharedMemory/PhysicsServerExample.cpp @@ -1444,23 +1444,7 @@ void PhysicsServerExample::stepSimulation(float deltaTime) - #if 0 - if (m_options == PHYSICS_SERVER_USE_RTC_CLOCK) - { - btClock rtc; - btScalar endTime = rtc.getTimeMilliseconds() + deltaTime*btScalar(800); - - while (rtc.getTimeMilliseconds()m_childGuiHelper->getRenderInterface()) { diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.cpp b/examples/SharedMemory/PhysicsServerSharedMemory.cpp index 5c967c9c4..f19620cbd 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsServerSharedMemory.cpp @@ -14,7 +14,8 @@ #include "PhysicsServerCommandProcessor.h" - +//number of shared memory blocks == number of simultaneous connections +#define MAX_SHARED_MEMORY_BLOCKS 2 struct PhysicsServerSharedMemoryInternalData { @@ -25,36 +26,39 @@ struct PhysicsServerSharedMemoryInternalData SharedMemoryInterface* m_sharedMemory; bool m_ownsSharedMemory; - SharedMemoryBlock* m_testBlock1; + SharedMemoryBlock* m_testBlocks[MAX_SHARED_MEMORY_BLOCKS]; int m_sharedMemoryKey; - bool m_isConnected; + bool m_areConnected[MAX_SHARED_MEMORY_BLOCKS]; bool m_verboseOutput; PhysicsServerCommandProcessor* m_commandProcessor; PhysicsServerSharedMemoryInternalData() :m_sharedMemory(0), m_ownsSharedMemory(false), - m_testBlock1(0), - m_sharedMemoryKey(SHARED_MEMORY_KEY), - m_isConnected(false), - m_verboseOutput(false), + m_sharedMemoryKey(SHARED_MEMORY_KEY), + m_verboseOutput(false), m_commandProcessor(0) { - + + for (int i=0;im_serverCommands[0]; + SharedMemoryStatus& serverCmd =m_testBlocks[blockIndex]->m_serverCommands[0]; serverCmd .m_type = statusType; serverCmd.m_sequenceNumber = sequenceNumber; serverCmd.m_timeStamp = timeStamp; return serverCmd; } - void submitServerStatus(SharedMemoryStatus& status) + void submitServerStatus(SharedMemoryStatus& status,int blockIndex) { - m_testBlock1->m_numServerCommands++; + m_testBlocks[blockIndex]->m_numServerCommands++; } }; @@ -84,9 +88,25 @@ PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* shar PhysicsServerSharedMemory::~PhysicsServerSharedMemory() { + m_data->m_commandProcessor->deleteDynamicsWorld(); delete m_data->m_commandProcessor; - delete m_data; + + if (m_data->m_sharedMemory) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_sharedMemory\n"); + } + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } + m_data->m_sharedMemory = 0; + } + + + delete m_data; } void PhysicsServerSharedMemory::resetDynamicsWorld() @@ -107,55 +127,61 @@ bool PhysicsServerSharedMemory::connectSharedMemory( struct GUIHelperInterface* bool allowCreation = true; + bool allConnected = false; + - if (m_data->m_isConnected) - { - b3Warning("connectSharedMemory, while already connected"); - return m_data->m_isConnected; - } + int counter = 0; - do - { + for (int block=0;blockm_areConnected[block]) + { + allConnected = true; + b3Warning("connectSharedMemory, while already connected"); + continue; + } + do + { - m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE,allowCreation); - if (m_data->m_testBlock1) - { - int magicId =m_data->m_testBlock1->m_magicId; - if (m_data->m_verboseOutput) - { - b3Printf("magicId = %d\n", magicId); - } - - if (m_data->m_testBlock1->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER) - { - InitSharedMemoryBlock(m_data->m_testBlock1); - if (m_data->m_verboseOutput) - { - b3Printf("Created and initialized shared memory block\n"); - } - m_data->m_isConnected = true; - } else - { - m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE); - m_data->m_testBlock1 = 0; - m_data->m_isConnected = false; - } - } else - { - b3Error("Cannot connect to shared memory"); - m_data->m_isConnected = false; - } - } while (counter++ < 10 && !m_data->m_isConnected); - - if (!m_data->m_isConnected) - { - b3Error("Server cannot connect to shared memory.\n"); - } + m_data->m_testBlocks[block] = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE,allowCreation); + if (m_data->m_testBlocks[block]) + { + int magicId =m_data->m_testBlocks[block]->m_magicId; + if (m_data->m_verboseOutput) + { + b3Printf("magicId = %d\n", magicId); + } + + if (m_data->m_testBlocks[block]->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER) + { + InitSharedMemoryBlock(m_data->m_testBlocks[block]); + if (m_data->m_verboseOutput) + { + b3Printf("Created and initialized shared memory block\n"); + } + m_data->m_areConnected[block] = true; + } else + { + m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE); + m_data->m_testBlocks[block] = 0; + m_data->m_areConnected[block] = false; + } + } else + { + b3Error("Cannot connect to shared memory"); + m_data->m_areConnected[block] = false; + } + } while (counter++ < 10 && !m_data->m_areConnected[block]); + if (!m_data->m_areConnected[block]) + { + b3Error("Server cannot connect to shared memory.\n"); + } + } - return m_data->m_isConnected; + return allConnected; } @@ -167,72 +193,34 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe { b3Printf("releaseSharedMemory1\n"); } - if (m_data->m_testBlock1) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_testBlock1\n"); - } - if (deInitializeSharedMemory) - { - m_data->m_testBlock1->m_magicId = 0; - if (m_data->m_verboseOutput) - { - b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlock1->m_magicId); - } - } - btAssert(m_data->m_sharedMemory); - m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE); - } - if (m_data->m_sharedMemory) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_sharedMemory\n"); - } - if (m_data->m_ownsSharedMemory) - { - delete m_data->m_sharedMemory; - } - m_data->m_sharedMemory = 0; - m_data->m_testBlock1 = 0; - } + for (int block = 0;blockm_testBlocks[block]) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_testBlock1\n"); + } + if (deInitializeSharedMemory) + { + m_data->m_testBlocks[block]->m_magicId = 0; + if (m_data->m_verboseOutput) + { + b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlocks[block]->m_magicId); + } + } + btAssert(m_data->m_sharedMemory); + m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE); + } + m_data->m_testBlocks[block] = 0; + m_data->m_areConnected[block] = false; + + } } void PhysicsServerSharedMemory::releaseSharedMemory() { - if (m_data->m_verboseOutput) - { - b3Printf("releaseSharedMemory1\n"); - } - if (m_data->m_testBlock1) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_testBlock1\n"); - } - m_data->m_testBlock1->m_magicId = 0; - if (m_data->m_verboseOutput) - { - b3Printf("magic id = %d\n",m_data->m_testBlock1->m_magicId); - } - btAssert(m_data->m_sharedMemory); - m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey -, SHARED_MEMORY_SIZE); - } - if (m_data->m_sharedMemory) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_sharedMemory\n"); - } - if (m_data->m_ownsSharedMemory) - { - delete m_data->m_sharedMemory; - } - m_data->m_sharedMemory = 0; - m_data->m_testBlock1 = 0; - } + disconnectSharedMemory(true); } @@ -250,30 +238,34 @@ void PhysicsServerSharedMemory::enableRealTimeSimulation(bool enableRealTimeSim) void PhysicsServerSharedMemory::processClientCommands() { - if (m_data->m_isConnected && m_data->m_testBlock1) + for (int block = 0;blockm_commandProcessor->replayLogCommand(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - ///we ignore overflow of integer for now - if (m_data->m_testBlock1->m_numClientCommands> m_data->m_testBlock1->m_numProcessedClientCommands) + if (m_data->m_areConnected[block] && m_data->m_testBlocks[block]) { - - - //until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands - btAssert(m_data->m_testBlock1->m_numClientCommands==m_data->m_testBlock1->m_numProcessedClientCommands+1); + m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - const SharedMemoryCommand& clientCmd =m_data->m_testBlock1->m_clientCommands[0]; + ///we ignore overflow of integer for now + if (m_data->m_testBlocks[block]->m_numClientCommands> m_data->m_testBlocks[block]->m_numProcessedClientCommands) + { + - m_data->m_testBlock1->m_numProcessedClientCommands++; - //todo, timeStamp - int timeStamp = 0; - SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp); - bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut,&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - if (hasStatus) - { - m_data->submitServerStatus(serverStatusOut); - } - + //until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands + btAssert(m_data->m_testBlocks[block]->m_numClientCommands==m_data->m_testBlocks[block]->m_numProcessedClientCommands+1); + + const SharedMemoryCommand& clientCmd =m_data->m_testBlocks[block]->m_clientCommands[0]; + + m_data->m_testBlocks[block]->m_numProcessedClientCommands++; + //todo, timeStamp + int timeStamp = 0; + SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp,block); + bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut,&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + if (hasStatus) + { + m_data->submitServerStatus(serverStatusOut,block); + } + + } } } } diff --git a/examples/SharedMemory/PosixSharedMemory.cpp b/examples/SharedMemory/PosixSharedMemory.cpp index 0297d43e2..9c16b3fe7 100644 --- a/examples/SharedMemory/PosixSharedMemory.cpp +++ b/examples/SharedMemory/PosixSharedMemory.cpp @@ -1,6 +1,7 @@ #include "PosixSharedMemory.h" #include "Bullet3Common/b3Logging.h" #include "LinearMath/btScalar.h" //for btAssert +#include "LinearMath/btAlignedObjectArray.h" //Windows implementation is in Win32SharedMemory.cpp #ifndef _WIN32 @@ -16,16 +17,28 @@ #endif +struct btSharedMemorySegment +{ + int m_key; + int m_sharedMemoryId; + void* m_sharedMemoryPtr; + bool m_createdSharedMemory; + + btSharedMemorySegment() + : m_sharedMemoryId(-1), + m_sharedMemoryPtr(0), + m_createdSharedMemory(true) + { + } + +}; + struct PosixSharedMemoryInteralData { - bool m_createdSharedMemory; - int m_sharedMemoryId; - void* m_sharedMemoryPtr; - + btAlignedObjectArray m_segments; + + PosixSharedMemoryInteralData() - :m_createdSharedMemory(false), - m_sharedMemoryId(-1), - m_sharedMemoryPtr(0) { } }; @@ -53,6 +66,27 @@ struct btPointerCaster void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCreation) { #ifdef TEST_SHARED_MEMORY + + { + btSharedMemorySegment* seg = 0; + int i=0; + + for (i=0;im_segments.size();i++) + { + if (m_internalData->m_segments[i].m_key == key) + { + seg = &m_internalData->m_segments[i]; + break; + } + } + if (seg) + { + b3Error("already created shared memory segment using same key"); + return seg->m_sharedMemoryPtr; + } + + } + int flags = (allowCreation ? IPC_CREAT : 0) | 0666; int id = shmget((key_t) key, (size_t) size,flags); if (id < 0) @@ -67,9 +101,12 @@ void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCr b3Error("shmat returned -1"); } else { - m_internalData->m_createdSharedMemory = allowCreation; - m_internalData->m_sharedMemoryId = id; - m_internalData->m_sharedMemoryPtr = result.ptr; + btSharedMemorySegment seg; + seg.m_key = key; + seg.m_createdSharedMemory = allowCreation; + seg.m_sharedMemoryId = id; + seg.m_sharedMemoryPtr = result.ptr; + m_internalData->m_segments.push_back(seg); return result.ptr; } } @@ -82,14 +119,33 @@ void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCr void PosixSharedMemory::releaseSharedMemory(int key, int size) { #ifdef TEST_SHARED_MEMORY - if (m_internalData->m_sharedMemoryId < 0) + + btSharedMemorySegment* seg = 0; + int i=0; + + for (i=0;im_segments.size();i++) + { + if (m_internalData->m_segments[i].m_key == key) + { + seg = &m_internalData->m_segments[i]; + break; + } + } + + if (0==seg) + { + b3Error("PosixSharedMemory::releaseSharedMemory: shared memory key not found"); + return; + } + + if (seg->m_sharedMemoryId < 0) { b3Error("PosixSharedMemory::releaseSharedMemory: shared memory id is not set"); } else { - if (m_internalData->m_createdSharedMemory) + if (seg->m_createdSharedMemory) { - int result = shmctl(m_internalData->m_sharedMemoryId,IPC_RMID,0); + int result = shmctl(seg->m_sharedMemoryId,IPC_RMID,0); if (result == -1) { b3Error("PosixSharedMemory::releaseSharedMemory: shmat returned -1"); @@ -97,15 +153,18 @@ void PosixSharedMemory::releaseSharedMemory(int key, int size) { b3Printf("PosixSharedMemory::releaseSharedMemory removed shared memory"); } - m_internalData->m_createdSharedMemory = false; - m_internalData->m_sharedMemoryId = -1; + seg->m_createdSharedMemory = false; + seg->m_sharedMemoryId = -1; } - if (m_internalData->m_sharedMemoryPtr) + if (seg->m_sharedMemoryPtr) { - shmdt(m_internalData->m_sharedMemoryPtr); - m_internalData->m_sharedMemoryPtr = 0; + shmdt(seg->m_sharedMemoryPtr); + seg->m_sharedMemoryPtr = 0; b3Printf("PosixSharedMemory::releaseSharedMemory detached shared memory\n"); } } + + m_internalData->m_segments.removeAtIndex(i); + #endif } diff --git a/src/LinearMath/btAlignedObjectArray.h b/src/LinearMath/btAlignedObjectArray.h index 146ae72e8..56f8189c1 100644 --- a/src/LinearMath/btAlignedObjectArray.h +++ b/src/LinearMath/btAlignedObjectArray.h @@ -476,15 +476,18 @@ protected: return index; } + void removeAtIndex(int index) + { + if (index