Click here to Skip to main content
15,887,683 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
Questionboost::named_mutex not released after process abort Pin
WernerP25-Jan-11 4:06
WernerP25-Jan-11 4:06 
AnswerRe: boost::named_mutex not released after process abort Pin
T210225-Jan-11 19:41
T210225-Jan-11 19:41 
GeneralRe: boost::named_mutex not released after process abort Pin
WernerP26-Jan-11 0:16
WernerP26-Jan-11 0:16 
GeneralRe: boost::named_mutex not released after process abort Pin
TheGreatAndPowerfulOz26-Jan-11 9:57
TheGreatAndPowerfulOz26-Jan-11 9:57 
GeneralRe: boost::named_mutex not released after process abort [modified] Pin
WernerP26-Jan-11 11:52
WernerP26-Jan-11 11:52 
AnswerRe: boost::named_mutex not released after process abort Pin
Chuck O'Toole26-Jan-11 18:20
Chuck O'Toole26-Jan-11 18:20 
GeneralRe: boost::named_mutex not released after process abort [modified] Pin
WernerP26-Jan-11 21:48
WernerP26-Jan-11 21:48 
GeneralRe: boost::named_mutex not released after process abort Pin
Chuck O'Toole26-Jan-11 23:42
Chuck O'Toole26-Jan-11 23:42 
Thanks for the details. So basically, you do not need the "synchronization" aspect of a mutex, just the "global name" aspect to check for exists / doesn't-exist check. I have used two methods for exactly this problem. Both methods "reset" when the image exits because Windows cleans up the objects.

One is to use "named pipes". This method has been suggested by other people in Code Project. You create a pipe with a known name agreed upon by the two processes. When you say "gui uses server", I assume you communicate in some way, you might even use pipes. I prefer this method when I need to also communicate between the processes as it provides for both a "single server instance" and the "interprocess communication".

Here's a routine I use to create an "inbound" pipe (the server code) in such a way as there will be only 1 instance. The error INVALID_HANDLE_VALUE indicates that you cannot create the pipe which is taken to mean that the pipe is already in use. I've "scrubbed" this a little to remove things I cannot share with you.

#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
#define FILE_FLAG_FIRST_PIPE_INSTANCE   0x00080000		// make VC 6.0 happy
#endif

#define RTLOCALIPC_WIN_SDDL \
	SDDL_DACL SDDL_DELIMINATOR \
	SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_GENERIC_ALL ";;;" SDDL_NETWORK SDDL_ACE_END \
	SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_GENERIC_ALL ";;;" SDDL_EVERYONE SDDL_ACE_END \
	SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_FILE_ALL ";;;" SDDL_LOCAL_SYSTEM SDDL_ACE_END


// Create an inbound pipe with a known name (e.g., "0CE7CCB0-6AB2-4c55-89C4-8EE95E759C30" from GUID tool)
HANDLE CreateInboundPipe(CString PName, bool first)
{
	CString ts;
	SECURITY_ATTRIBUTES *SecAttrs = NULL;
	DWORD dwOpenMode;
	DWORD dwPipeMode;

	// The following is conditionalized to allow old VC++ 6.0 to compile this module.  However,
	// programs build with VC++ 6.0 should *not* be creating new inbound pipes.  Those programs
	// should be using VS 2005 or later.  This is because the Security requirements for Vista
	// makes us use a security attribute that excludes the network (local IPC only) and you need
	// VS 2005 or later for that to work properly.  VC++ 6.0 clients should only open outbound pipes.

	PSECURITY_DESCRIPTOR pSecDesc = NULL;
        ConvertStringSecurityDescriptorToSecurityDescriptor(RTLOCALIPC_WIN_SDDL, SDDL_REVISION_1, &pSecDesc, NULL);
	SecAttrs = (SECURITY_ATTRIBUTES *)malloc(sizeof(SECURITY_ATTRIBUTES));
	SecAttrs->nLength = sizeof(SECURITY_ATTRIBUTES);
	SecAttrs->lpSecurityDescriptor = pSecDesc;
	SecAttrs->bInheritHandle = FALSE;

	dwOpenMode = PIPE_ACCESS_DUPLEX | (first ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0);
	dwPipeMode = PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT;
	ts.Format("\\\\.\\pipe\\%s", PName);
	ThePipe = CreateNamedPipe(ts, dwOpenMode, dwPipeMode, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, NMPWAIT_USE_DEFAULT_WAIT, SecAttrs);	// security attribute
	free(SecAttrs);
	LocalFree(pSecDesc);
	return ThePipe;
}

The "client" can then try to connect to the same pipe name and if it discovers that the server isn't available, it could start an instance of the server. Again "scrubbed" a bit since I can't cut / paste the entire routine.
// Form a connection to a known name (e.g., "0CE7CCB0-6AB2-4c55-89C4-8EE95E759C30" from GUID tool)
HANDLE ConnectToServer(CString PName, bool NoRetry)
{
	CString ts;
	int retry = 0;

	ts.Format("\\\\.\\pipe\\%s", PName);								 // form actual pipe name
	while (1) 
	{ 
		ThePipe = CreateFile(ts, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 

		if ((NoRetry) || (ThePipe != INVALID_HANDLE_VALUE))				// if that worked (or no retries), we're done here
			break; 

		if (GetLastError() == ERROR_PIPE_BUSY)							// if the server is busy, wait for it
		{
			WaitNamedPipe(ts, NMPWAIT_WAIT_FOREVER);
		}
		else
		{
			if (retry++ == 0)											// first retry will attempt to start the image, only try this once 
			{
// here's where you'd stick some code to start an instance
// of your server and return ThePipe handle value on success
			}
								// need to run somebody but can't, say "Invalid Handle Value"
			if (retry > (GIVE_UP_TIMER / GIVE_UP_SLEEP))
				break;
			Sleep(GIVE_UP_SLEEP);										// give it a moment (or a half a moment) to start up before retrying
		}
	} 
	if (ThePipe != INVALID_HANDLE_VALUE)								// OK, if it worked, we have a few more things to do
	{ 
		DWORD dwMode = PIPE_READMODE_MESSAGE;							// The pipe connected; change to message-read mode
		SetNamedPipeHandleState(ThePipe, &dwMode, NULL, NULL);			// set mode and nothing else
		Connected = true;
	}
	return ThePipe;
}

since these are part of a larger Class, there are some Class Members I don't show, like ThePipe, the Timeouts, etc. But you should be able to figure those out.

The other method I use, especially for "short lived processes" is to simply open a known file with GENERIC_WRITE, in other words, take out an exclusive access lock on a shared file. Only 1 process can do this and the kernel manages that. The kernel will "close" the access when the image exits so cleanup is easy. If the "client" can get the exclusive access lock, then the server is not running so it can release the file and then start the server. This method does suffer from some timing issues and you'll need a retry mechanism like the one used for the pipes to avoid some startup problems.
QuestionNeed interface index for recvd UDP packets Pin
Dave_25-Jan-11 3:50
Dave_25-Jan-11 3:50 
AnswerRe: Need interface index for recvd UDP packets Pin
HimanshuJoshi25-Jan-11 5:43
HimanshuJoshi25-Jan-11 5:43 
QuestionSet AutoRun fail under win 7 [modified][solved] Pin
yu-jian25-Jan-11 2:57
yu-jian25-Jan-11 2:57 
AnswerRe: Set AutoRun fail under win 7 Pin
Code-o-mat25-Jan-11 3:17
Code-o-mat25-Jan-11 3:17 
AnswerRe: Set AutoRun fail under win 7 Pin
CPallini25-Jan-11 3:20
mveCPallini25-Jan-11 3:20 
AnswerRe: Set AutoRun fail under win 7 Pin
Hans Dietrich25-Jan-11 3:47
mentorHans Dietrich25-Jan-11 3:47 
AnswerRe: Set AutoRun fail under win 7 Pin
Richard MacCutchan25-Jan-11 4:47
mveRichard MacCutchan25-Jan-11 4:47 
GeneralRe: Set AutoRun fail under win 7 Pin
yu-jian25-Jan-11 6:28
yu-jian25-Jan-11 6:28 
AnswerRe: Set AutoRun fail under win 7 Pin
yu-jian25-Jan-11 6:13
yu-jian25-Jan-11 6:13 
Questionshadow copy, deep copy and bitwie copy by constructor Pin
aesthetic.crazy25-Jan-11 2:26
aesthetic.crazy25-Jan-11 2:26 
AnswerRe: shadow copy, deep copy and bitwie copy by constructor Pin
CPallini25-Jan-11 2:44
mveCPallini25-Jan-11 2:44 
AnswerRe: shadow copy, deep copy and bitwie copy by constructor Pin
T210225-Jan-11 2:59
T210225-Jan-11 2:59 
AnswerRe: shadow copy, deep copy and bitwie copy by constructor Pin
Nemanja Trifunovic25-Jan-11 5:03
Nemanja Trifunovic25-Jan-11 5:03 
AnswerRe: shadow copy, deep copy and bitwie copy by constructor Pin
Andrew Brock25-Jan-11 5:11
Andrew Brock25-Jan-11 5:11 
QuestionDialogBar in SDI in MDI applcatiion Pin
Anu_Bala24-Jan-11 22:37
Anu_Bala24-Jan-11 22:37 
QuestionHow can i delete History and Cookies Directory in Internet explorer? Pin
yogish29324-Jan-11 19:18
yogish29324-Jan-11 19:18 
AnswerRe: How can i delete History and Cookies Directory in Internet explorer? Pin
KingsGambit24-Jan-11 20:18
KingsGambit24-Jan-11 20:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.