| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -52,6 +52,8 @@ class SHMProcess::Private
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        suspended = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        identified = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        useYield = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        my_SVfileLock = -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        my_CLfileLock = -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ~Private(){};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    memory_info * my_descriptor;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -60,6 +62,8 @@ class SHMProcess::Private
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    char *my_shm;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int my_shmid;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Process* q;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int my_SVfileLock;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int my_CLfileLock;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool attached;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool suspended;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -70,6 +74,9 @@ class SHMProcess::Private
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool Aux_Core_Attach(bool & versionOK, pid_t & PID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool waitWhile (uint32_t state);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool GetLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    bool AreLocksOk();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    void FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// some helpful macros to keep the code bloat in check
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -95,7 +102,8 @@ bool SHMProcess::Private::waitWhile (uint32_t state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if(cnt == 10000)// check if the other process is still there
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            shmctl(my_shmid, IPC_STAT, &descriptor); 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            /*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            shmctl(my_shmid, IPC_STAT, &descriptor);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if(descriptor.shm_nattch == 1)// DF crashed or exited - no way to tell?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                //detach the shared memory
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -112,6 +120,24 @@ bool SHMProcess::Private::waitWhile (uint32_t state)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                cnt = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if(!AreLocksOk())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                //detach the shared memory
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                shmdt(my_shm);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                attached = suspended = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                // we aren't the current process anymore
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                g_pProcess = NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                throw Error::SHMServerDisappeared();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                cnt = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if(useYield)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -166,6 +192,72 @@ bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool SHMProcess::Private::AreLocksOk()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // both locks are inited (we hold our lock)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(my_CLfileLock != -1 && my_SVfileLock != -1) 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if(lockf(my_SVfileLock,F_TEST,0) == -1) // and server holds its lock
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return true; // OK, locks are good
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // locks are bad
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void SHMProcess::Private::FreeLocks()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(my_CLfileLock != -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lockf(my_CLfileLock,F_ULOCK,0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close(my_CLfileLock);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        my_CLfileLock = -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(my_SVfileLock != -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close(my_SVfileLock);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        my_SVfileLock = -1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool SHMProcess::Private::GetLocks()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    char name[256];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // try to acquire locks
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // look at the server lock, if it's locked, the server is present
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sprintf(name, "/tmp/DFHack/%d/SVlock",my_pid,name);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    my_SVfileLock = open(name,O_WRONLY);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(my_SVfileLock == -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(lockf( my_SVfileLock, F_TEST, 0 ) != -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close(my_SVfileLock);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // open the client lock, try to lock it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sprintf(name, "/tmp/DFHack/%d/CLlock",my_pid,name);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    my_CLfileLock = open(name,O_WRONLY);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(my_CLfileLock == -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close(my_SVfileLock);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(lockf(my_CLfileLock,F_TLOCK, 0) == -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // couldn't acquire lock
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close(my_SVfileLock);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        close(my_CLfileLock);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // ok, we have all the locks!
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				: d(new Private())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -189,18 +281,15 @@ SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * Check if there are two processes connected to the segment
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     */
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    shmid_ds descriptor;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    shmctl(d->my_shmid, IPC_STAT, &descriptor); 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(descriptor.shm_nattch != 2)// badness
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // set pid and gets lock for it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    d->my_pid = PID;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(!d->GetLocks())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fprintf(stderr,"dfhack: %d : invalid no. of processes connected\n", (int) descriptor.shm_nattch);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fprintf(stderr,"detach: %d",shmdt(d->my_shm));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fprintf(stderr,"Couldn't get locks for PID %d'\n", PID);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        shmdt(d->my_shm);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				   
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     * Test bridge version, get PID, sync Yield
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				     */
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -209,12 +298,16 @@ SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fprintf(stderr,"DF terminated during reading\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        shmdt(d->my_shm);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // free locks
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(!bridgeOK)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        fprintf(stderr,"SHM bridge version mismatch\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        shmdt(d->my_shm);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // free locks
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -225,6 +318,8 @@ SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        perror("readlink");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        shmdt(d->my_shm);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // free locks
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -240,6 +335,9 @@ SHMProcess::SHMProcess(uint32_t PID, vector< memory_info* >& known_versions)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // 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()
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -410,9 +508,16 @@ bool SHMProcess::attach()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int status;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(g_pProcess != 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cerr << "there's already a different process attached" << endl;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // FIXME: throw exception here - programmer error
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cerr << "client is already attached to a process!" << endl;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if(!d->GetLocks())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cerr << "server is full or not really there!" << endl;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    /*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    * Attach the segment
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    */
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -427,10 +532,12 @@ bool SHMProcess::attach()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->attached = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        cerr << "unable to suspend" << endl;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // FIXME: detach sehment here
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        shmdt(d->my_shm);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    cerr << "unable to attach" << endl;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    d->FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -451,9 +558,11 @@ bool SHMProcess::detach()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->suspended = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->my_shm = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        g_pProcess = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        d->FreeLocks();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // fail if we can't detach
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // FIXME: throw exception here??
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    perror("failed to detach shared segment");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |