tags:

views:

110

answers:

5

In C++, I have a resource that is tied to a pid. Sometimes the process associated with that pid exits abnormally and leaks the resource.

Therefore, I'm thinking of putting the pid in the file that records the resource as being in use. Then when I go to get a resource, if I see an item as registered as being in use, I would search to see whether a process matching the pid is currently running, and if not, clean up the leaked resource.

I realize there is a very small probability that a new unrealated pid is now sharing the same number, but this is better than leaking with no clean up I have now.

Alternatively, perhaps there is a better solution for this, if so, please suggest, otherwise, I'll pursue the pid recording.

Further details: The resource is a port number for communication between a client and a server over tcp. Only one instance of the client may use a given port number on a machine. The port numbers are taken from a range of available port numbers to use. While the client is running, it notes the port number it is using in a special file on disk and then cleans this entry up on exit. For abnormal exit, this does not always get cleaned up and the port number is left annotated as being in use, when it is no longer being used.

+4  A: 

To check for existence of process with a given id, use kill(pid,0) (I assume you are on POSIX system). See man 2 kill for details.

Also, you can use waitpid call to be notified when the process finishes.

Roman Cheplyaka
+3  A: 

I would recommend you use some kind of OS resource, not a PID. Mutexes, semaphores, delete-on-close files. All of these are cleaned up by the OS when a process exits.

On Windows, I would recommend a named mutex.

On Linux, I would recommend using flock on a file.

Dark Falcon
I am not aware of a way to do delete-on-close on Linux. Note that you can delete a file while still having it open, then it will be deleted when the last file handle is closed. Of course, once deleted, the only way to access it is through one of the existing handles, so this may not be useful to you.
Dark Falcon
@Dark: True, but the `flock` (advisory lock on a file) will be released. That is something other processes can detect. Still, I'd probably go for Roman's suggestion of using `kill(PID, 0)`, or check the existence of `/proc/1234` for PID 1234. (But your comment confuses me a little. Did you reply to a comment that was subsequently deleted?)
Christopher Creutzig
A: 

The problem domain isn't clear, unfortunately, you could try re-explaining it in some other way.

But if I understand you correctly, you could create a map like

std::map< ProcessId, boost::shared_ptr<Resource> > map;
// `Resource` here references to some abstract resource type
// and `ProcessId` on Windows system would be basically a DWORD

and in this case you simply have to list every running process (this can be done via EnumProcesses call on Windows) and remove every entry with inappropriate id from your map. After doing this you would have only valid process-resource pairs left. This action can be repeated every YY seconds depending on your needs.

Note that in this case removing an item from your map would basically call the corresponding destructor (because, if your resource is not being used in your code somewhere else, it's reference count would drop to zero).

Kotti
A: 

The API that achieves that on windows are OpenProcess which takes process ID as input, and GetExitCodeProcess which returns STILL_ACTIVE when the process is, well, still active. You could also use any Wait function with zero timeout, but this API seems somewhat cleaner.

As other answers note, however, this doesn't seem a promising road to take. We might be able to give more focused advice if you provide more scenario details. What is your platform? What is the leaked resource exactly? Do you have access to the leaking app code? Can you wrap it in a high-level try-catch with some cleanup? If not, maybe wait on the leaker to finish with a dedicated thread (or dedicated process altogether)? Any detail you provide might help.

Ofek Shilon
More details are now added above.
WilliamKF
So - is it indeed windows? Is the said client part of your code? Do the suggested alternatives make sense in your case?
Ofek Shilon
Since the title indicates Linux, I doubt that references to Windows API functions are all that helpful.
Christopher Creutzig
+2  A: 

How about a master process that starts your process (the one which terminates abnormally) waits for your process to crash (waitpid) and spawns it again when waitpid returns.

while(1) {
fork exec
waitpid
}
neal aise
This is the only sane way to manage processes, at least on Unix.
Nikolai N Fetissov