Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. boost::named_mutex not released after process abort

boost::named_mutex not released after process abort

Scheduled Pinned Locked Moved C / C++ / MFC
questionannouncementc++data-structuresperformance
8 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    WernerP
    wrote on last edited by
    #1

    OS Version: Windows XP Pro boost Version: 1.44.0 Hi, I want to monitor, whether a certain process is running. The program of the process is written in C++ and is a console app. I've chosen the mutex concept, because I want to restrict usage of the program's main to exactly one thread. First I used the example from the boost site, which places the scoped_lock within the main routine's block. But when the app was terminated via the close button of the console window the scoped_lock destructor was not called which had a negative side effect: The mutex is associated with a file :| in the All Users\Application Data tree, directory boost_interprocess and if this file is not deleted, the mutex can not be acquired, although it is no more referenced by any application. Hence I wrapped the mutex into a global object (1) to instantiate it as soon as possible (2) to release it under as many circumstances of program termination as possible via the wrapper's destructor. This is the wrapper's class - you can see the mutex is non-blocking and controlled via a scoped lock struct ApplicationLock { ApplicationLock() : appmutex(open_or_create, "SilvaCoreMutex"), applock(appmutex, try_to_lock) {} bool alreadylocked() { return (applock == 0); } private: named_mutex appmutex; scoped_lock<named_mutex> applock; }; ApplicationLock appliclock; If the console window is closed, the desctructor is called and the mutex released. But if the process is terminated due to a crash or aborted via the task manager, the mutex is not released. Even a system restart doesn't release it. I thought a mutex should be held in a memory shared area and exclusively depend on this shared area and never depend on anything which is stored in the file system. How can I get rid of that mutex, when it is no more referenced by any application. Have I chosen the wrong concept? Have I misunderstood the boost mutex technique? Thanks in advance Werner

    T C 2 Replies Last reply
    0
    • W WernerP

      OS Version: Windows XP Pro boost Version: 1.44.0 Hi, I want to monitor, whether a certain process is running. The program of the process is written in C++ and is a console app. I've chosen the mutex concept, because I want to restrict usage of the program's main to exactly one thread. First I used the example from the boost site, which places the scoped_lock within the main routine's block. But when the app was terminated via the close button of the console window the scoped_lock destructor was not called which had a negative side effect: The mutex is associated with a file :| in the All Users\Application Data tree, directory boost_interprocess and if this file is not deleted, the mutex can not be acquired, although it is no more referenced by any application. Hence I wrapped the mutex into a global object (1) to instantiate it as soon as possible (2) to release it under as many circumstances of program termination as possible via the wrapper's destructor. This is the wrapper's class - you can see the mutex is non-blocking and controlled via a scoped lock struct ApplicationLock { ApplicationLock() : appmutex(open_or_create, "SilvaCoreMutex"), applock(appmutex, try_to_lock) {} bool alreadylocked() { return (applock == 0); } private: named_mutex appmutex; scoped_lock<named_mutex> applock; }; ApplicationLock appliclock; If the console window is closed, the desctructor is called and the mutex released. But if the process is terminated due to a crash or aborted via the task manager, the mutex is not released. Even a system restart doesn't release it. I thought a mutex should be held in a memory shared area and exclusively depend on this shared area and never depend on anything which is stored in the file system. How can I get rid of that mutex, when it is no more referenced by any application. Have I chosen the wrong concept? Have I misunderstood the boost mutex technique? Thanks in advance Werner

      T Offline
      T Offline
      T2102
      wrote on last edited by
      #2

      If you have time, you can try reading Lock & Wait Synchronization in C++[^] Why can't you prevent your process from being spawned by counting the number of running instances and not creating a new instance if one already exists? Then you only need a lock on that tiny code block.

      W 1 Reply Last reply
      0
      • T T2102

        If you have time, you can try reading Lock & Wait Synchronization in C++[^] Why can't you prevent your process from being spawned by counting the number of running instances and not creating a new instance if one already exists? Then you only need a lock on that tiny code block.

        W Offline
        W Offline
        WernerP
        wrote on last edited by
        #3

        Thank you. Then I would hold the counter in a shared memory area. Which technique would you recommend for the shm? I would prefer one, which is platform independent to a high degree. I've experimented with the shared memory class in boost::interprocess. The boost shm object again seemed to create a file in the Application Data dir. I don't like this so much, because it is dependent on access restrictions to the fs.And this would not be necessary, because I'm just using ram. Werner

        T 1 Reply Last reply
        0
        • W WernerP

          Thank you. Then I would hold the counter in a shared memory area. Which technique would you recommend for the shm? I would prefer one, which is platform independent to a high degree. I've experimented with the shared memory class in boost::interprocess. The boost shm object again seemed to create a file in the Application Data dir. I don't like this so much, because it is dependent on access restrictions to the fs.And this would not be necessary, because I'm just using ram. Werner

          T Offline
          T Offline
          TheGreatAndPowerfulOz
          wrote on last edited by
          #4

          then try locking a file in the temp directory.

          "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

          W 1 Reply Last reply
          0
          • T TheGreatAndPowerfulOz

            then try locking a file in the temp directory.

            "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

            W Offline
            W Offline
            WernerP
            wrote on last edited by
            #5

            Thank you, this I think is basically ok, but I would like the lock to be deleted, when the process, that created it crashes, which is not the case with a boost::named_mutex or a temp file, and on windows using such directories like temp and appdata a.s.o is always fuss, because they are rarely organised the same on all Windows NT systems and often not named the same and often not defined within the same system variable. If I had read the boost documentation before :| I had not been so surprised, that the mutex and the shm are opening a file because these objects have 'kernel or filesystem' persistence which on Windows seems to be always filesystem. Such objects need an explicit call to their remove function to remove the file. What I'm looking for is an interprocess object with process persistence. Cheers Werner

            modified on Wednesday, January 26, 2011 6:46 PM

            1 Reply Last reply
            0
            • W WernerP

              OS Version: Windows XP Pro boost Version: 1.44.0 Hi, I want to monitor, whether a certain process is running. The program of the process is written in C++ and is a console app. I've chosen the mutex concept, because I want to restrict usage of the program's main to exactly one thread. First I used the example from the boost site, which places the scoped_lock within the main routine's block. But when the app was terminated via the close button of the console window the scoped_lock destructor was not called which had a negative side effect: The mutex is associated with a file :| in the All Users\Application Data tree, directory boost_interprocess and if this file is not deleted, the mutex can not be acquired, although it is no more referenced by any application. Hence I wrapped the mutex into a global object (1) to instantiate it as soon as possible (2) to release it under as many circumstances of program termination as possible via the wrapper's destructor. This is the wrapper's class - you can see the mutex is non-blocking and controlled via a scoped lock struct ApplicationLock { ApplicationLock() : appmutex(open_or_create, "SilvaCoreMutex"), applock(appmutex, try_to_lock) {} bool alreadylocked() { return (applock == 0); } private: named_mutex appmutex; scoped_lock<named_mutex> applock; }; ApplicationLock appliclock; If the console window is closed, the desctructor is called and the mutex released. But if the process is terminated due to a crash or aborted via the task manager, the mutex is not released. Even a system restart doesn't release it. I thought a mutex should be held in a memory shared area and exclusively depend on this shared area and never depend on anything which is stored in the file system. How can I get rid of that mutex, when it is no more referenced by any application. Have I chosen the wrong concept? Have I misunderstood the boost mutex technique? Thanks in advance Werner

              C Offline
              C Offline
              Chuck OToole
              wrote on last edited by
              #6

              I'm not sure I understand what you intend to do with the "Mutex". It seems that you simply want to ensure that only one instantiation of the application runs. You haven't been clear what the "2nd" instantiation, the one who finds the "lock" taken will do as a result. Will it "exit", will it "wait for the 1st application to exit". Depending on your intended use, there may be different approaches. A Mutex might not be the appropriate solution.

              W 1 Reply Last reply
              0
              • C Chuck OToole

                I'm not sure I understand what you intend to do with the "Mutex". It seems that you simply want to ensure that only one instantiation of the application runs. You haven't been clear what the "2nd" instantiation, the one who finds the "lock" taken will do as a result. Will it "exit", will it "wait for the 1st application to exit". Depending on your intended use, there may be different approaches. A Mutex might not be the appropriate solution.

                W Offline
                W Offline
                WernerP
                wrote on last edited by
                #7

                Hi, the application which I'm working on is based on a client server architecture |java gui| <- gsoap -> |c++ server| where the server is a windows or unix program, which embeds the business logic. I want to make a gui for users, who don't need to know about that and simply start the gui as if it was the whole app. Thus the gui is managing server instantiation - gui started && server not running => gui starts server. gui started && server running => gui uses server. server has no more session within timeout => server exits gracefully. So what I actually would need is a singleton server and this would mean to query the OS for the existence of the server process. Java has no method to query process lists on a system independent level or to check, whether there is a certain process running - there's just rudimentary support for process control. Java is gui standard here. So I made a little app (nmmutex) which is supposed to control a named mutex for the server's main thread. This app exits always and writes it's result (acquired, not acquired) to the return code. The mutex is queried in a non-blocking manner (try_to_lock). Java can run that process via Runtime.exec. Using that mutex, the server itself may control, whether there is already an instance running. It also can try_to_lock the mutex, and if it's not available, may return. The server itself could also take the role of nmmutex, i.e. to query the mutex. The caveat of using the mutex is, as far as I understood, that boost interprocess objects like mutex and shared memory due to portability have 'kernel or filesystem' persistence. On windows it's filesystem persistence. So if the server crashes, it might not be restartable even after a reboot. And the user can't tell why. I tend to dislike the mutex idea meanwhile, although using it seemed logical to me first: I wanted to restrict use of server's main block to a single thread. I could try to get a soap session at gui startup and assume the server does not run when it fails. Or maybe there's a library which hides querys to the os, like process list, behind a portable interface. Cheers Werner

                modified on Thursday, January 27, 2011 4:00 AM

                C 1 Reply Last reply
                0
                • W WernerP

                  Hi, the application which I'm working on is based on a client server architecture |java gui| <- gsoap -> |c++ server| where the server is a windows or unix program, which embeds the business logic. I want to make a gui for users, who don't need to know about that and simply start the gui as if it was the whole app. Thus the gui is managing server instantiation - gui started && server not running => gui starts server. gui started && server running => gui uses server. server has no more session within timeout => server exits gracefully. So what I actually would need is a singleton server and this would mean to query the OS for the existence of the server process. Java has no method to query process lists on a system independent level or to check, whether there is a certain process running - there's just rudimentary support for process control. Java is gui standard here. So I made a little app (nmmutex) which is supposed to control a named mutex for the server's main thread. This app exits always and writes it's result (acquired, not acquired) to the return code. The mutex is queried in a non-blocking manner (try_to_lock). Java can run that process via Runtime.exec. Using that mutex, the server itself may control, whether there is already an instance running. It also can try_to_lock the mutex, and if it's not available, may return. The server itself could also take the role of nmmutex, i.e. to query the mutex. The caveat of using the mutex is, as far as I understood, that boost interprocess objects like mutex and shared memory due to portability have 'kernel or filesystem' persistence. On windows it's filesystem persistence. So if the server crashes, it might not be restartable even after a reboot. And the user can't tell why. I tend to dislike the mutex idea meanwhile, although using it seemed logical to me first: I wanted to restrict use of server's main block to a single thread. I could try to get a soap session at gui startup and assume the server does not run when it fails. Or maybe there's a library which hides querys to the os, like process list, behind a portable interface. Cheers Werner

                  modified on Thursday, January 27, 2011 4:00 AM

                  C Offline
                  C Offline
                  Chuck OToole
                  wrote on last edited by
                  #8

                  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);
                  SecAt
                  
                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups