Developer forums (C::B DEVELOPMENT STRICTLY!) > Development
Non-DDE IPC?
thomas:
Actually this code snippet is almost exactly what we need (forget the DLL stuff):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/using_shared_memory_in_a_dynamic_link_library.asp
Darn, lol... should have looked at MSDN earlier. 8)
TheNullinator:
The memory mapped file IPC system is going pretty well. About up to the WM_COPYDATA system's usefulness. It is sending the files to the last active window quite well. The custum queue that resides in the shared memory (64K) seems to be holding up, too.
There are some issues when the currently active window is closed and you open a file from Explorer before activating one of the other windows. The file gets stuck in the queue because noone can claim it. I'm adding a check now to see if the window a file wanted to be opened in is destroyed and if so it will be adopted by the next active window.
Code::Blocks also likes to hang after being closed (only instances that had the main window). It needs a bit of help from the Task Manager to be on it's merry way. It doesn't use any CPU time, it just never terminates.
TheNullinator:
--- Quote from: thomas on April 07, 2006, 04:23:59 pm ---Actually this code snippet is almost exactly what we need (forget the DLL stuff):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/using_shared_memory_in_a_dynamic_link_library.asp
Darn, lol... should have looked at MSDN earlier. 8)
--- End quote ---
Pretty good example, that one. :) Quite a good idea, too.
thomas:
--- Quote ---There are some issues when the currently active window is closed and you open a file from Explorer before activating one of the other windows. The file gets stuck in the queue because noone can claim it.
--- End quote ---
This is no problem at all if you use the semaphore approach instead of messaging a window. The worst thing to happen is you might lose one "open file" event, but for this to happen, you would have to hit the window's close box and open the next file within, say 0.1 seconds or so... :lol:
* When the application starts, the shared memory area either exists, or it does not.
* If it does not exist, you start as usual. Some time later, during your application's OnIdle function, the semaphore is queried regularly (non-blocking). It costs very few CPU cycles to do that. At some point, its status will be signalled, so you know that you have data waiting for you.
* If the SHM does already exist, you know at least one other process must be running. Thus, you lock the mutex, append to the list, release the mutex, and signal the semaphore. Then you exit the application (closing the file mapping, of course). You don't bother to create a window or initialise the application in any way. This will probably take only a fraction of a second.
* When the last instance has terminated, all file mappings are closed, so there is no SHM any more. If you used a memory mapped file (not just system VM), then the OS will save the data to disk, otherwise it will discard the data. The next instance that starts will know that it is the primary instance.
* The only possible pitfall is that the primary instance could be closed just at the very same time as another instance is still busy writing to the SHM. You have to click very fast to achieve this.
Anyway, what will happen? Nothing:
* The worst thing to happen is that the application does not open these files. So what, you just closed it! Of course you would not expect the application to open more files if you close it, so that is perfectly good behaviour.
* Still, if this is a problem, you can simply post the semaphore once during startup for good. There is no harm in doing so (except wasting ~200 CPU cycles once).
* After starting up, the application will eventually get into OnIdle, and will see that the semaphore is signalled (because you just posted it). It will therefore look at the list and find any data that may be there (or find nothing, which is fine, too).
TheNullinator:
--- Quote from: thomas on April 07, 2006, 07:58:06 pm ---This is no problem at all if you use the semaphore approach instead of messaging a window.
--- End quote ---
I'm not using any window messages or WindowProcs any more nor the registry for storing the current window handle (now stored in the shared memory as you suggested). :) The problem was fixed when I fixed the hang on exit for an instance with a window.
This is the basic flow of things in OnInit:
* Create 64K named shared memory.
* Map the memory. If this is the first instance, initialize some data in the memory
* Create the semaphore initially unsignalled.
* Create the mutex which is initially owned.
* If this is not the first instance and files were passed on the command line, wait for a window to exist (handle stored at the start of the shared memory) and make it the foreground window (if done just before loading the file in OnIdle, it sometimes doesn't work on XP and never works on ME) using mutex protection, add the files to the queue using mutex protection increasing the semaphore count for each file, and then terminate.
* Create the main frame and register it as the current window to receive new files.
* Release the mutex so files can be added to the queue.
In OnIdle the state of the semaphore is checked and if signalled and a file exists in the queue for this instance's window or can be taken from a no longer existing window (can only be done by activating this instance's window), remove it from the queue and open it. If no file existed for this window, the semaphore count is kept correct.
It (ANSI build) seems to work quite well under both XP and ME at the moment. I'm yet to do a unicode build for testing on XP. More tests and code tidy-ups planned for tomorrow morning. I'll post a diff when satisfied that all issues are sorted out on my two Windows boxes.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version