|  |  | @ -43,96 +43,77 @@ class SHMProcess::Private | 
			
		
	
		
		
			
				
					
					|  |  |  |     public: |  |  |  |     public: | 
			
		
	
		
		
			
				
					
					|  |  |  |     Private() |  |  |  |     Private() | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         my_descriptor = NULL; |  |  |  |         memdescriptor = NULL; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_pid = 0; |  |  |  |         process_ID = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_shm = 0; |  |  |  |         shm_addr = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_shmid = -1; |  |  |  |         //shm_addr_with_cl_idx = 0;
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_window = NULL; |  |  |  |         shm_ID = -1; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         window = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |         attached = false; |  |  |  |         attached = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         suspended = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         identified = false; |  |  |  |         identified = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         useYield = false; |  |  |  |         useYield = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         my_SVfileLock = -1; |  |  |  |         server_lock = -1; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_CLfileLock = -1; |  |  |  |         client_lock = -1; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         suspend_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         attachmentIdx = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         locked = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     }; |  |  |  |     }; | 
			
		
	
		
		
			
				
					
					|  |  |  |     ~Private(){}; |  |  |  |     ~Private(){}; | 
			
		
	
		
		
			
				
					
					|  |  |  |     memory_info * my_descriptor; |  |  |  |     memory_info * memdescriptor; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     DFWindow * my_window; |  |  |  |     DFWindow * window; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     pid_t my_pid; |  |  |  |     pid_t process_ID; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     char *my_shm; |  |  |  |     char *shm_addr; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     int my_shmid; |  |  |  |     int shm_ID; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     Process* q; |  |  |  |     Process* q; | 
			
		
	
		
		
			
				
					
					|  |  |  |     int my_SVfileLock; |  |  |  |     int server_lock; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     int my_CLfileLock; |  |  |  |     int client_lock; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     int suspend_lock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     int attachmentIdx; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool attached; |  |  |  |     bool attached; | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool suspended; |  |  |  |     bool locked; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     bool identified; |  |  |  |     bool identified; | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool useYield; |  |  |  |     bool useYield; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool validate(char* exe_file, uint32_t pid, std::vector< memory_info* >& known_versions); |  |  |  |     bool validate(std::vector< memory_info* >& known_versions); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool Aux_Core_Attach(bool & versionOK, pid_t & PID); |  |  |  |     bool Aux_Core_Attach(bool & versionOK, pid_t & PID); | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool waitWhile (uint32_t state); |  |  |  |     //bool waitWhile (uint32_t state);
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     bool SetAndWait (uint32_t state); | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool GetLocks(); |  |  |  |     bool GetLocks(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool AreLocksOk(); |  |  |  |     bool AreLocksOk(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     void FreeLocks(); |  |  |  |     void FreeLocks(); | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // some helpful macros to keep the code bloat in check
 |  |  |  | #define SHMCMD ( (uint32_t *) shm_addr)[attachmentIdx] | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | #define SHMCMD ((shm_cmd *)my_shm)->pingpong |  |  |  | #define D_SHMCMD ( (uint32_t *) (d->shm_addr))[d->attachmentIdx] | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | #define D_SHMCMD ((shm_cmd *)d->my_shm)->pingpong |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define SHMHDR ((shm_core_hdr *)my_shm) |  |  |  | #define SHMHDR ((shm_core_hdr *)shm_addr) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | #define D_SHMHDR ((shm_core_hdr *)d->my_shm) |  |  |  | #define D_SHMHDR ((shm_core_hdr *)(d->shm_addr)) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define SHMDATA(type) ((type *)(my_shm + SHM_HEADER)) |  |  |  | #define SHMDATA(type) ((type *)(shm_addr + SHM_HEADER)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | #define D_SHMDATA(type) ((type *)(d->my_shm + SHM_HEADER)) |  |  |  | #define D_SHMDATA(type) ((type *)(d->shm_addr + SHM_HEADER)) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /*
 |  |  |  | bool SHMProcess::Private::SetAndWait (uint32_t state) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | Yeah. with no way to synchronize things (locks are slow, the OS doesn't give us enough control over scheduling) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | we end up with this silly thing |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::Private::waitWhile (uint32_t state) |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     uint32_t cnt = 0; |  |  |  |     uint32_t cnt = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     struct shmid_ds descriptor; |  |  |  |     if(!attached) return false; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     SHMCMD = state; | 
			
		
	
		
		
			
				
					
					|  |  |  |     while (SHMCMD == state) |  |  |  |     while (SHMCMD == state) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(cnt == 10000)// check if the other process is still there
 |  |  |  |         if(cnt == 10000)// check if the other process is still there, don't hammer the kernel too much.
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |              |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             /*
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             shmctl(my_shmid, IPC_STAT, &descriptor); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(descriptor.shm_nattch == 1)// DF crashed or exited - no way to tell?
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //detach the shared memory
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 shmdt(my_shm); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 attached = suspended = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // we aren't the current process anymore
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 g_pProcess = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 throw Error::SHMServerDisappeared(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 cnt = 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(!AreLocksOk()) |  |  |  |             if(!AreLocksOk()) | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //detach the shared memory
 |  |  |  |                 //detach the shared memory
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 shmdt(my_shm); |  |  |  |                 shmdt(shm_addr); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 attached = suspended = false; |  |  |  |                 FreeLocks(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |                 attached = locked = identified = false; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 // we aren't the current process anymore
 |  |  |  |                 // we aren't the current process anymore
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 g_pProcess = NULL; |  |  |  |                 g_pProcess = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 FreeLocks(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                 throw Error::SHMServerDisappeared(); |  |  |  |                 throw Error::SHMServerDisappeared(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             else |  |  |  |             else | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
	
		
		
			
				
					|  |  | @ -145,12 +126,9 @@ bool SHMProcess::Private::waitWhile (uint32_t state) | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         cnt++; |  |  |  |         cnt++; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // server returned a generic error
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(SHMCMD == CORE_ERROR) |  |  |  |     if(SHMCMD == CORE_ERROR) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         SHMCMD = CORE_RUNNING; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         attached = suspended = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         cerr << "shm server error!" << endl; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         assert (false); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     return true; |  |  |  |     return true; | 
			
		
	
	
		
		
			
				
					|  |  | @ -160,9 +138,9 @@ bool SHMProcess::Private::waitWhile (uint32_t state) | 
			
		
	
		
		
			
				
					
					|  |  |  | Yeah. with no way to synchronize things (locks are slow, the OS doesn't give us enough control over scheduling) |  |  |  | Yeah. with no way to synchronize things (locks are slow, the OS doesn't give us enough control over scheduling) | 
			
		
	
		
		
			
				
					
					|  |  |  | we end up with this silly thing |  |  |  | we end up with this silly thing | 
			
		
	
		
		
			
				
					
					|  |  |  | */ |  |  |  | */ | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::waitWhile (uint32_t state) |  |  |  | bool SHMProcess::SetAndWait (uint32_t state) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->waitWhile(state); |  |  |  |     return d->SetAndWait(state); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | uint32_t OS_getAffinity() |  |  |  | uint32_t OS_getAffinity() | 
			
		
	
	
		
		
			
				
					|  |  | @ -174,30 +152,13 @@ uint32_t OS_getAffinity() | 
			
		
	
		
		
			
				
					
					|  |  |  |     return affinity; |  |  |  |     return affinity; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | // test if we have client and server locks and the server is present
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     SHMCMD = CORE_ATTACH; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!waitWhile(CORE_ATTACH)) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     versionOK =( SHMDATA(coreattach)->sv_version == CORE_VERSION ); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     PID = SHMDATA(coreattach)->sv_PID; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     useYield = SHMDATA(coreattach)->sv_useYield; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     #ifdef DEBUG |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(useYield) cerr << "Using Yield!" << endl; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     #endif |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::Private::AreLocksOk() |  |  |  | bool SHMProcess::Private::AreLocksOk() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // both locks are inited (we hold our lock)
 |  |  |  |     // both locks are inited (we hold our lock)
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(my_CLfileLock != -1 && my_SVfileLock != -1)  |  |  |  |     if(client_lock != -1 && server_lock != -1)  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(lockf(my_SVfileLock,F_TEST,0) == -1) // and server holds its lock
 |  |  |  |         if(lockf(server_lock,F_TEST,0) == -1) // and server holds its lock
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |             return true; // OK, locks are good
 |  |  |  |             return true; // OK, locks are good
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -208,16 +169,23 @@ bool SHMProcess::Private::AreLocksOk() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::Private::FreeLocks() |  |  |  | void SHMProcess::Private::FreeLocks() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(my_CLfileLock != -1) |  |  |  |     attachmentIdx = -1; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(client_lock != -1) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         lockf(client_lock,F_ULOCK,0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         close(client_lock); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         client_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(server_lock != -1) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         lockf(my_CLfileLock,F_ULOCK,0); |  |  |  |         close(server_lock); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         close(my_CLfileLock); |  |  |  |         server_lock = -1; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_CLfileLock = -1; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(my_SVfileLock != -1) |  |  |  |     if(suspend_lock != -1) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         close(my_SVfileLock); |  |  |  |         close(suspend_lock); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         my_SVfileLock = -1; |  |  |  |         locked = false; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         suspend_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -226,123 +194,102 @@ bool SHMProcess::Private::GetLocks() | 
			
		
	
		
		
			
				
					
					|  |  |  |     char name[256]; |  |  |  |     char name[256]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     // try to acquire locks
 |  |  |  |     // try to acquire locks
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     // look at the server lock, if it's locked, the server is present
 |  |  |  |     // look at the server lock, if it's locked, the server is present
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     sprintf(name, "/tmp/DFHack/%d/SVlock",my_pid,name); |  |  |  |     sprintf(name, "/tmp/DFHack/%d/SVlock",process_ID); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     my_SVfileLock = open(name,O_WRONLY); |  |  |  |     server_lock = open(name,O_WRONLY); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if(my_SVfileLock == -1) |  |  |  |     if(server_lock == -1) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // cerr << "can't open sv lock" << endl;
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(lockf( my_SVfileLock, F_TEST, 0 ) != -1) |  |  |  |     if(lockf( server_lock, F_TEST, 0 ) != -1) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         close(my_SVfileLock); |  |  |  |         cerr << "sv lock not locked" << endl; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         close(server_lock); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         server_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     // open the client lock, try to lock it
 |  |  |  |     for(int i = 0; i < SHM_MAX_CLIENTS; i++) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     sprintf(name, "/tmp/DFHack/%d/CLlock",my_pid,name); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     my_CLfileLock = open(name,O_WRONLY); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(my_CLfileLock == -1) |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         close(my_SVfileLock); |  |  |  |         // open the client suspend locked
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         sprintf(name, "/tmp/DFHack/%d/CLSlock%d",process_ID,i); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |         suspend_lock = open(name,O_WRONLY); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if(lockf(my_CLfileLock,F_TLOCK, 0) == -1) |  |  |  |         if(suspend_lock == -1) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |         { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // couldn't acquire lock
 |  |  |  |             cerr << "can't open cl S-lock " << i << endl; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         close(my_SVfileLock); |  |  |  |             // couldn't open lock
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         close(my_CLfileLock); |  |  |  |             continue; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // open the client lock, try to lock it
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         sprintf(name, "/tmp/DFHack/%d/CLlock%d",process_ID,i); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         client_lock = open(name,O_WRONLY); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(client_lock == -1) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             cerr << "can't open cl lock " << i << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             close(suspend_lock); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             locked = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             suspend_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // couldn't open lock
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(lockf(client_lock,F_TLOCK, 0) == -1) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             // couldn't acquire lock
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             cerr << "can't acquire cl lock " << i << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             close(suspend_lock); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             locked = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             suspend_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             close(client_lock); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             client_lock = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             continue; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // ok, we have all the locks we need!
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         attachmentIdx = i; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // ok, we have all the locks!
 |  |  |  |     close(server_lock); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     return true; |  |  |  |     server_lock = -1; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     cerr << "can't get any client locks" << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions) |  |  |  | SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions) | 
			
		
	
		
		
			
				
					
					|  |  |  | : d(new Private()) |  |  |  | : d(new Private()) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     char exe_link_name [256]; |  |  |  |     d->process_ID = PID; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     char target_name[1024]; |  |  |  |     if(!attach()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     int target_result; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /*
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Locate the segment. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if ((d->my_shmid = shmget(SHM_KEY + PID, SHM_SIZE, 0666)) < 0) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /*
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Attach the segment |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if ((d->my_shm = (char *) shmat(d->my_shmid, NULL, 0)) == (char *) -1) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // set pid and gets lock for it
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     d->my_pid = PID; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!d->GetLocks()) |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         fprintf(stderr,"Couldn't get locks for PID %d'\n", PID); |  |  |  |         // couldn't attach to process
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         shmdt(d->my_shm); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     /*
 |  |  |  |     /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Test bridge version, get PID, sync Yield |  |  |  |      * Test bridge version, get PID, sync Yield | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     bool bridgeOK; |  |  |  |     bool bridgeOK; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!d->Aux_Core_Attach(bridgeOK,d->my_pid)) |  |  |  |     if(!d->Aux_Core_Attach(bridgeOK,d->process_ID)) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         fprintf(stderr,"DF terminated during reading\n"); |  |  |  |         detach(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         shmdt(d->my_shm); |  |  |  |         throw Error::SHMAttachFailure(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // free locks
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->FreeLocks(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!bridgeOK) |  |  |  |     if(!bridgeOK) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         fprintf(stderr,"SHM bridge version mismatch\n"); |  |  |  |         detach(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         shmdt(d->my_shm); |  |  |  |         throw Error::SHMVersionMismatch(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         // free locks
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->FreeLocks(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // find the binary
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     sprintf(exe_link_name,"/proc/%d/exe", d->my_pid); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (target_result == -1) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         perror("readlink"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         shmdt(d->my_shm); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         // free locks
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->FreeLocks(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     // make sure we have a null terminated string...
 |  |  |  |     // try to identify the DF version (md5 the binary, compare with known versions)
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     // see http://www.opengroup.org/onlinepubs/000095399/functions/readlink.html
 |  |  |  |     d->validate(known_versions); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     target_name[target_result] = 0; |  |  |  |     d->window = new DFWindow(this); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     // try to identify the DF version
 |  |  |  |     // detach
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     d->validate(target_name, d->my_pid, known_versions); |  |  |  |     detach(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     d->my_window = new DFWindow(this); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // at this point, DF is stopped and waiting for commands. make it run again
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_RUNNING; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     shmdt(d->my_shm); // detach so we don't attach twice when attach() is called
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // free locks
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     d->FreeLocks(); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::isSuspended() |  |  |  | bool SHMProcess::isSuspended() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->suspended; |  |  |  |     return d->locked; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::isAttached() |  |  |  | bool SHMProcess::isAttached() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
	
		
		
			
				
					|  |  | @ -354,13 +301,28 @@ bool SHMProcess::isIdentified() | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->identified; |  |  |  |     return d->identified; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::Private::validate(char * exe_file, uint32_t pid, vector <memory_info *> & known_versions) |  |  |  | bool SHMProcess::Private::validate(vector <memory_info *> & known_versions) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     char exe_link_name [256]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     char target_name[1024]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     int target_result; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // find the binary
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     sprintf(exe_link_name,"/proc/%d/exe", process_ID); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     target_result = readlink(exe_link_name, target_name, sizeof(target_name)-1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (target_result == -1) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         perror("readlink"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // make sure we have a null terminated string...
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // see http://www.opengroup.org/onlinepubs/000095399/functions/readlink.html
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     target_name[target_result] = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     md5wrapper md5; |  |  |  |     md5wrapper md5; | 
			
		
	
		
		
			
				
					
					|  |  |  |     // get hash of the running DF process
 |  |  |  |     // get hash of the running DF process
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     string hash = md5.getHashFromFile(exe_file); |  |  |  |     string hash = md5.getHashFromFile(target_name); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     vector<memory_info *>::iterator it; |  |  |  |     vector<memory_info *>::iterator it; | 
			
		
	
		
		
			
				
					
					|  |  |  |     cerr << exe_file << " " << hash <<  endl; |  |  |  |     // cerr << exe_file << " " << hash <<  endl;
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     // iterate over the list of memory locations
 |  |  |  |     // iterate over the list of memory locations
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) |  |  |  |     for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -368,10 +330,9 @@ bool SHMProcess::Private::validate(char * exe_file, uint32_t pid, vector <memory | 
			
		
	
		
		
			
				
					
					|  |  |  |             if(hash == (*it)->getString("md5")) // are the md5 hashes the same?
 |  |  |  |             if(hash == (*it)->getString("md5")) // are the md5 hashes the same?
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |             { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 memory_info * m = *it; |  |  |  |                 memory_info * m = *it; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 my_descriptor = m; |  |  |  |                 memdescriptor = m; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 my_pid = pid; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 identified = true; |  |  |  |                 identified = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 cerr << "identified " << m->getVersion() << endl; |  |  |  |                 // cerr << "identified " << m->getVersion() << endl;
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 return true; |  |  |  |                 return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -390,31 +351,37 @@ SHMProcess::~SHMProcess() | 
			
		
	
		
		
			
				
					
					|  |  |  |         detach(); |  |  |  |         detach(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // destroy data model. this is assigned by processmanager
 |  |  |  |     // destroy data model. this is assigned by processmanager
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(d->my_window) |  |  |  |     if(d->window) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         delete d->my_window; |  |  |  |         delete d->window; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     delete d; |  |  |  |     delete d; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | memory_info * SHMProcess::getDescriptor() |  |  |  | memory_info * SHMProcess::getDescriptor() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->my_descriptor; |  |  |  |     return d->memdescriptor; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | DFWindow * SHMProcess::getWindow() |  |  |  | DFWindow * SHMProcess::getWindow() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->my_window; |  |  |  |     return d->window; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | int SHMProcess::getPID() |  |  |  | int SHMProcess::getPID() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->my_pid; |  |  |  |     return d->process_ID; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //FIXME: implement
 |  |  |  | // there is only one we care about.
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::getThreadIDs(vector<uint32_t> & threads ) |  |  |  | bool SHMProcess::getThreadIDs(vector<uint32_t> & threads ) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(d->attached) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         threads.clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         threads.push_back(d->process_ID); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     return false; |  |  |  |     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -424,7 +391,7 @@ void SHMProcess::getMemRanges( vector<t_memrange> & ranges ) | 
			
		
	
		
		
			
				
					
					|  |  |  |     char buffer[1024]; |  |  |  |     char buffer[1024]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     char permissions[5]; // r/-, w/-, x/-, p/s, 0
 |  |  |  |     char permissions[5]; // r/-, w/-, x/-, p/s, 0
 | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     sprintf(buffer, "/proc/%lu/maps", d->my_pid); |  |  |  |     sprintf(buffer, "/proc/%lu/maps", d->process_ID); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     FILE *mapFile = ::fopen(buffer, "r"); |  |  |  |     FILE *mapFile = ::fopen(buffer, "r"); | 
			
		
	
		
		
			
				
					
					|  |  |  |     uint64_t offset, device1, device2, node; |  |  |  |     uint64_t offset, device1, device2, node; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
	
		
		
			
				
					|  |  | @ -451,37 +418,79 @@ bool SHMProcess::suspend() | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(d->suspended) |  |  |  |     if(d->locked) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return true; |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_SUSPEND; |  |  |  |      | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if(!waitWhile(CORE_SUSPEND)) |  |  |  |     // FIXME: this should be controlled on the server side
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // FIXME: IF server got CORE_RUN in this frame, interpret CORE_SUSPEND as CORE_STEP
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // did we just resume a moment ago?
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(D_SHMCMD == CORE_RUN) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         //fprintf(stderr,"%d invokes step\n",d->attachmentIdx);
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // wait for the next window
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(!d->SetAndWait(CORE_STEP)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     else | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         //fprintf(stderr,"%d invokes suspend\n",d->attachmentIdx);
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         // lock now
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(!d->SetAndWait(CORE_SUSPEND)) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw Error::SHMLockingError("if(!d->SetAndWait(CORE_SUSPEND))"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     d->suspended = true; |  |  |  |     //fprintf(stderr,"waiting for lock\n");
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     return true; |  |  |  |     // we wait for the server to give up our suspend lock (held by default)
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(lockf(d->suspend_lock,F_LOCK,0) == 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         d->locked = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // FIXME: needs a good think-through
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::asyncSuspend() |  |  |  | bool SHMProcess::asyncSuspend() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!d->attached) |  |  |  |     if(!d->attached) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(d->suspended) |  |  |  |     if(d->locked) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return true; |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(D_SHMCMD == CORE_SUSPENDED) |  |  |  |     uint32_t cmd = D_SHMCMD; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(cmd == CORE_SUSPENDED) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->suspended = true; |  |  |  |         // we have to hold the lock to be really suspended
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         return true; |  |  |  |         if(lockf(d->suspend_lock,F_LOCK,0) == 0) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             d->locked = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMCMD = CORE_SUSPEND; |  |  |  |         // did we just resume a moment ago?
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(cmd == CORE_STEP) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         else if(cmd == CORE_RUN) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             D_SHMCMD = CORE_STEP; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             D_SHMCMD = CORE_SUSPEND; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | @ -491,21 +500,30 @@ bool SHMProcess::forceresume() | 
			
		
	
		
		
			
				
					
					|  |  |  |     return resume(); |  |  |  |     return resume(); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // FIXME: wait for the server to advance a step!
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::resume() |  |  |  | bool SHMProcess::resume() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!d->attached) |  |  |  |     if(!d->attached) | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!d->suspended) |  |  |  |     if(!d->locked) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return true; |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_RUNNING; |  |  |  |     // unlock the suspend lock
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     d->suspended = false; |  |  |  |     if(lockf(d->suspend_lock,F_ULOCK,0) == 0) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     return true; |  |  |  |     { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         d->locked = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(d->SetAndWait(CORE_RUN)) // we have to make sure the server responds!
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         throw Error::SHMLockingError("if(d->SetAndWait(CORE_RUN))"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     throw Error::SHMLockingError("if(lockf(d->suspend_lock,F_ULOCK,0) == 0)"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return false; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::attach() |  |  |  | bool SHMProcess::attach() | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     int status; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(g_pProcess != 0) |  |  |  |     if(g_pProcess != 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         // FIXME: throw exception here - programmer error
 |  |  |  |         // FIXME: throw exception here - programmer error
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -514,31 +532,39 @@ bool SHMProcess::attach() | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!d->GetLocks()) |  |  |  |     if(!d->GetLocks()) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         cerr << "server is full or not really there!" << endl; |  |  |  |         //cerr << "server is full or not really there!" << endl;
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     * Locate the segment. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if ((d->shm_ID = shmget(SHM_KEY + d->process_ID, SHM_SIZE, 0666)) < 0) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         d->FreeLocks(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         cerr << "can't find segment" << endl; // FIXME: throw
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     /*
 |  |  |  |     /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     * Attach the segment |  |  |  |     * Attach the segment | 
			
		
	
		
		
			
				
					
					|  |  |  |     */ |  |  |  |     */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     if ((d->my_shm = (char *) shmat(d->my_shmid, NULL, 0)) != (char *) -1) |  |  |  |     if ((d->shm_addr = (char *) shmat(d->shm_ID, NULL, 0)) == (char *) -1) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->attached = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(suspend()) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             d->suspended = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             g_pProcess = this; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             return true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->attached = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         cerr << "unable to suspend" << endl; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         shmdt(d->my_shm); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->FreeLocks(); |  |  |  |         d->FreeLocks(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         cerr << "can't attach segment" << endl; // FIXME: throw
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     cerr << "unable to attach" << endl; |  |  |  |     d->attached = true; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     d->FreeLocks(); |  |  |  |     if(!suspend()) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     return false; |  |  |  |     { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         shmdt(d->shm_addr); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         d->FreeLocks(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         cerr << "unable to suspend" << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     g_pProcess = this; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return true; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::detach() |  |  |  | bool SHMProcess::detach() | 
			
		
	
	
		
		
			
				
					|  |  | @ -547,18 +573,18 @@ bool SHMProcess::detach() | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(d->suspended) |  |  |  |     if(d->locked) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         resume(); |  |  |  |         resume(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // detach segment
 |  |  |  |     // detach segment
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(shmdt(d->my_shm) != -1) |  |  |  |     if(shmdt(d->shm_addr) != -1) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         d->FreeLocks(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         d->locked = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->attached = false; |  |  |  |         d->attached = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->suspended = false; |  |  |  |         d->shm_addr = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         d->my_shm = 0; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         g_pProcess = 0; |  |  |  |         g_pProcess = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |         d->FreeLocks(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return true; |  |  |  |         return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // fail if we can't detach
 |  |  |  |     // fail if we can't detach
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -569,15 +595,16 @@ bool SHMProcess::detach() | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) |  |  |  | void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     // normal read under 1MB
 |  |  |  |     // normal read under 1MB
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(size <= SHM_BODY) |  |  |  |     if(size <= SHM_BODY) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMHDR->address = src_address; |  |  |  |         D_SHMHDR->address = src_address; | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMHDR->length = size; |  |  |  |         D_SHMHDR->length = size; | 
			
		
	
		
		
			
				
					
					|  |  |  |         gcc_barrier |  |  |  |         gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMCMD = CORE_DFPP_READ; |  |  |  |         d->SetAndWait(CORE_READ); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         waitWhile(CORE_DFPP_READ); |  |  |  |         memcpy (target_buffer, D_SHMDATA(void),size); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         memcpy (target_buffer, d->my_shm + SHM_HEADER,size); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // a big read, we pull data over the shm in iterations
 |  |  |  |     // a big read, we pull data over the shm in iterations
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
	
		
		
			
				
					|  |  | @ -590,9 +617,8 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff | 
			
		
	
		
		
			
				
					
					|  |  |  |             D_SHMHDR->address = src_address; |  |  |  |             D_SHMHDR->address = src_address; | 
			
		
	
		
		
			
				
					
					|  |  |  |             D_SHMHDR->length = to_read; |  |  |  |             D_SHMHDR->length = to_read; | 
			
		
	
		
		
			
				
					
					|  |  |  |             gcc_barrier |  |  |  |             gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |             D_SHMCMD = CORE_DFPP_READ; |  |  |  |             d->SetAndWait(CORE_READ); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             waitWhile(CORE_DFPP_READ); |  |  |  |             memcpy (target_buffer, D_SHMDATA(void) ,size); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             memcpy (target_buffer, d->my_shm + SHM_HEADER,size); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             // decrease size by bytes read
 |  |  |  |             // decrease size by bytes read
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             size -= to_read; |  |  |  |             size -= to_read; | 
			
		
	
		
		
			
				
					
					|  |  |  |             // move the cursors
 |  |  |  |             // move the cursors
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -606,54 +632,60 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | uint8_t SHMProcess::readByte (const uint32_t offset) |  |  |  | uint8_t SHMProcess::readByte (const uint32_t offset) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_BYTE; |  |  |  |     d->SetAndWait(CORE_READ_BYTE); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_BYTE); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     return D_SHMHDR->value; |  |  |  |     return D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) |  |  |  | void SHMProcess::readByte (const uint32_t offset, uint8_t &val ) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_BYTE; |  |  |  |     d->SetAndWait(CORE_READ_BYTE); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_BYTE); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     val = D_SHMHDR->value; |  |  |  |     val = D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t SHMProcess::readWord (const uint32_t offset) |  |  |  | uint16_t SHMProcess::readWord (const uint32_t offset) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_WORD; |  |  |  |     d->SetAndWait(CORE_READ_WORD); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_WORD); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     return D_SHMHDR->value; |  |  |  |     return D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::readWord (const uint32_t offset, uint16_t &val) |  |  |  | void SHMProcess::readWord (const uint32_t offset, uint16_t &val) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_WORD; |  |  |  |     d->SetAndWait(CORE_READ_WORD); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_WORD); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     val = D_SHMHDR->value; |  |  |  |     val = D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | uint32_t SHMProcess::readDWord (const uint32_t offset) |  |  |  | uint32_t SHMProcess::readDWord (const uint32_t offset) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_DWORD; |  |  |  |     d->SetAndWait(CORE_READ_DWORD); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_DWORD); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     return D_SHMHDR->value; |  |  |  |     return D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) |  |  |  | void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_DWORD; |  |  |  |     d->SetAndWait(CORE_READ_DWORD); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_DWORD); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     val = D_SHMHDR->value; |  |  |  |     val = D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -663,43 +695,47 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::writeDWord (uint32_t offset, uint32_t data) |  |  |  | void SHMProcess::writeDWord (uint32_t offset, uint32_t data) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->value = data; |  |  |  |     D_SHMHDR->value = data; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_WRITE_DWORD; |  |  |  |     d->SetAndWait(CORE_WRITE_DWORD); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_WRITE_DWORD); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // using these is expensive.
 |  |  |  | // using these is expensive.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::writeWord (uint32_t offset, uint16_t data) |  |  |  | void SHMProcess::writeWord (uint32_t offset, uint16_t data) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->value = data; |  |  |  |     D_SHMHDR->value = data; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_WRITE_WORD; |  |  |  |     d->SetAndWait(CORE_WRITE_WORD); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_WRITE_WORD); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::writeByte (uint32_t offset, uint8_t data) |  |  |  | void SHMProcess::writeByte (uint32_t offset, uint8_t data) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->value = data; |  |  |  |     D_SHMHDR->value = data; | 
			
		
	
		
		
			
				
					
					|  |  |  |     gcc_barrier |  |  |  |     gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_WRITE_BYTE; |  |  |  |     d->SetAndWait(CORE_WRITE_BYTE); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_WRITE_BYTE); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) |  |  |  | void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     // normal write under 1MB
 |  |  |  |     // normal write under 1MB
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(size <= SHM_BODY) |  |  |  |     if(size <= SHM_BODY) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMHDR->address = dst_address; |  |  |  |         D_SHMHDR->address = dst_address; | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMHDR->length = size; |  |  |  |         D_SHMHDR->length = size; | 
			
		
	
		
		
			
				
					
					|  |  |  |         memcpy(d->my_shm+SHM_HEADER,source_buffer, size); |  |  |  |         memcpy(D_SHMDATA(void),source_buffer, size); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         gcc_barrier |  |  |  |         gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |         D_SHMCMD = CORE_WRITE; |  |  |  |         d->SetAndWait(CORE_WRITE); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         waitWhile(CORE_WRITE); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     // a big write, we push this over the shm in iterations
 |  |  |  |     // a big write, we push this over the shm in iterations
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
	
		
		
			
				
					|  |  | @ -711,10 +747,9 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf | 
			
		
	
		
		
			
				
					
					|  |  |  |             // write to_write bytes to dst_cursor
 |  |  |  |             // write to_write bytes to dst_cursor
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             D_SHMHDR->address = dst_address; |  |  |  |             D_SHMHDR->address = dst_address; | 
			
		
	
		
		
			
				
					
					|  |  |  |             D_SHMHDR->length = to_write; |  |  |  |             D_SHMHDR->length = to_write; | 
			
		
	
		
		
			
				
					
					|  |  |  |             memcpy(d->my_shm+SHM_HEADER,source_buffer, to_write); |  |  |  |             memcpy(D_SHMDATA(void),source_buffer, to_write); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             gcc_barrier |  |  |  |             gcc_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |             D_SHMCMD = CORE_WRITE; |  |  |  |             d->SetAndWait(CORE_WRITE); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             waitWhile(CORE_WRITE); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             // decrease size by bytes written
 |  |  |  |             // decrease size by bytes written
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             size -= to_write; |  |  |  |             size -= to_write; | 
			
		
	
		
		
			
				
					
					|  |  |  |             // move the cursors
 |  |  |  |             // move the cursors
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -729,6 +764,8 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf | 
			
		
	
		
		
			
				
					
					|  |  |  | // FIXME: butt-fugly
 |  |  |  | // FIXME: butt-fugly
 | 
			
		
	
		
		
			
				
					
					|  |  |  | const std::string SHMProcess::readCString (uint32_t offset) |  |  |  | const std::string SHMProcess::readCString (uint32_t offset) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |     std::string temp; |  |  |  |     std::string temp; | 
			
		
	
		
		
			
				
					
					|  |  |  |     char temp_c[256]; |  |  |  |     char temp_c[256]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     int counter = 0; |  |  |  |     int counter = 0; | 
			
		
	
	
		
		
			
				
					|  |  | @ -746,6 +783,8 @@ const std::string SHMProcess::readCString (uint32_t offset) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | DfVector SHMProcess::readVector (uint32_t offset, uint32_t item_size) |  |  |  | DfVector SHMProcess::readVector (uint32_t offset, uint32_t item_size) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     /*
 |  |  |  |     /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         GNU libstdc++ vector is three pointers long |  |  |  |         GNU libstdc++ vector is three pointers long | 
			
		
	
		
		
			
				
					
					|  |  |  |         ptr start |  |  |  |         ptr start | 
			
		
	
	
		
		
			
				
					|  |  | @ -762,38 +801,42 @@ DfVector SHMProcess::readVector (uint32_t offset, uint32_t item_size) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | const std::string SHMProcess::readSTLString(uint32_t offset) |  |  |  | const std::string SHMProcess::readSTLString(uint32_t offset) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     full_barrier |  |  |  |     full_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_STL_STRING; |  |  |  |     d->SetAndWait(CORE_READ_STL_STRING); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_STL_STRING); |  |  |  |     return(string( D_SHMDATA(char) )); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     //int length = ((shm_retval *)d->my_shm)->value;
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return(string( (char *)d->my_shm+SHM_HEADER)); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) |  |  |  | size_t SHMProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = offset; |  |  |  |     D_SHMHDR->address = offset; | 
			
		
	
		
		
			
				
					
					|  |  |  |     full_barrier |  |  |  |     full_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_READ_STL_STRING; |  |  |  |     d->SetAndWait(CORE_READ_STL_STRING); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_READ_STL_STRING); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     size_t length = D_SHMHDR->value; |  |  |  |     size_t length = D_SHMHDR->value; | 
			
		
	
		
		
			
				
					
					|  |  |  |     size_t fit = min(bufcapacity - 1, length); |  |  |  |     size_t fit = min(bufcapacity - 1, length); | 
			
		
	
		
		
			
				
					
					|  |  |  |     strncpy(buffer,(char *)d->my_shm+SHM_HEADER,fit); |  |  |  |     strncpy(buffer,D_SHMDATA(char),fit); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     buffer[fit] = 0; |  |  |  |     buffer[fit] = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     return fit; |  |  |  |     return fit; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) |  |  |  | void SHMProcess::writeSTLString(const uint32_t address, const std::string writeString) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMHDR->address = address; |  |  |  |     D_SHMHDR->address = address; | 
			
		
	
		
		
			
				
					
					|  |  |  |     strncpy(d->my_shm+SHM_HEADER,writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator
 |  |  |  |     strncpy(D_SHMDATA(char),writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     full_barrier |  |  |  |     full_barrier | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_WRITE_STL_STRING; |  |  |  |     d->SetAndWait(CORE_WRITE_STL_STRING); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     waitWhile(CORE_WRITE_STL_STRING); |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | string SHMProcess::readClassName (uint32_t vptr) |  |  |  | string SHMProcess::readClassName (uint32_t vptr) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |     int typeinfo = readDWord(vptr - 0x4); |  |  |  |     int typeinfo = readDWord(vptr - 0x4); | 
			
		
	
		
		
			
				
					
					|  |  |  |     int typestring = readDWord(typeinfo + 0x4); |  |  |  |     int typestring = readDWord(typeinfo + 0x4); | 
			
		
	
		
		
			
				
					
					|  |  |  |     string raw = readCString(typestring); |  |  |  |     string raw = readCString(typestring); | 
			
		
	
	
		
		
			
				
					|  |  | @ -802,22 +845,18 @@ string SHMProcess::readClassName (uint32_t vptr) | 
			
		
	
		
		
			
				
					
					|  |  |  |     return raw.substr(start,end-start - 2); // trim the 'st' from the end
 |  |  |  |     return raw.substr(start,end-start - 2); // trim the 'st' from the end
 | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // FIXME: having this around could lead to bad things in the hands of unsuspecting fools
 |  |  |  | // get module index by name and version. bool 0 = error
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | // *!!DON'T BE AN UNSUSPECTING FOOL!!*
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // the whole SHM thing works only because copying DWORDS is an atomic operation on i386 and x86_64 archs
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // get module index by name and version. bool 1 = error
 |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) |  |  |  | bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     modulelookup * payload = (modulelookup *) (d->my_shm + SHM_HEADER); |  |  |  |     if(!d->locked) throw Error::SHMAccessDenied(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     modulelookup * payload = D_SHMDATA(modulelookup); | 
			
		
	
		
		
			
				
					
					|  |  |  |     payload->version = version; |  |  |  |     payload->version = version; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     strncpy(payload->name,name,255); |  |  |  |     strncpy(payload->name,name,255); | 
			
		
	
		
		
			
				
					
					|  |  |  |     payload->name[255] = 0; |  |  |  |     payload->name[255] = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     full_barrier |  |  |  |     if(!SetAndWait(CORE_ACQUIRE_MODULE)) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     D_SHMCMD = CORE_ACQUIRE_MODULE; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!waitWhile(CORE_ACQUIRE_MODULE)) |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; // FIXME: throw a fatal exception instead
 |  |  |  |         return false; // FIXME: throw a fatal exception instead
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					|  |  | @ -832,5 +871,26 @@ bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | char * SHMProcess::getSHMStart (void) |  |  |  | char * SHMProcess::getSHMStart (void) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     return d->my_shm; |  |  |  |     if(!d->locked) return 0; //THROW HERE!
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |          | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return /*d->shm_addr_with_cl_idx*/ d->shm_addr; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!locked) throw Error::SHMAccessDenied(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     SHMDATA(coreattach)->cl_affinity = OS_getAffinity(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if(!SetAndWait(CORE_ATTACH)) return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     /*
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     cerr <<"CORE_VERSION" << CORE_VERSION << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     cerr <<"server CORE_VERSION" << SHMDATA(coreattach)->sv_version << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     versionOK =( SHMDATA(coreattach)->sv_version == CORE_VERSION ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     PID = SHMDATA(coreattach)->sv_PID; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     useYield = SHMDATA(coreattach)->sv_useYield; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     #ifdef DEBUG | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if(useYield) cerr << "Using Yield!" << endl; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return true; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } |