Re: [Plplot-devel] C++ help requested for step 1. (fwd)
Hi Alan I'm not sure how exactly the two classes interact, but if the parameters for the constructor will be the same every time you can pass them in as constant values. I.e, I presume the size will be the same each time and you could use a static member to hold a name that you increment after each use and pass in on next construction. Phil Sent from my Windows 10 phone From: Alan W. Irwin Sent: 05 February 2017 22:35 To: Phil Rosenberg Cc: PLplot development list Subject: Re: [Plplot-devel] C++ help requested for step 1. (fwd) On 2017-02-05 21:16- Phil Rosenberg wrote: [...] > As it stands I don't see in your source code where you have called > m_unamed_semaphore_MemoryMap.create( ); > > I think what is happening is that you construct your PLnamedMutex > which constructs all the member variables using their default > constructors (the ones which take no variables). The default > constructor for PLMemoryMap just sets m_buffer to NULL. Your call to > getwsem then takes m_buffer, which is NULL and tries to access some of > it's data and I imagine that is the point that everything goes wrong. > OK. That completely explains my gdb results. All the members of the shmbuf struct appear to well aligned so there is no padding. So the address of wsem (the first member) is exactly the same as the value of m_buffer (the address of the struct) which is NULL according to your above reasoning. And on Linux, sem_t consumes 32 bytes for 64-bit systems and size_t consumes 8 bytes. So buf is offset from the start of the struct by 2*32 + 8 = 72 bytes = 0x48 which is the (bad) gdb result I got for the address of buf. So it appears I am getting consistently wrong results in the PLNamedMutex case for anything to do with PLMemoryMap because of the default constructor used for PLMemoryMap. > Anyway, the fix is to either call m_unamed_semaphore_MemoryMap.create > just before getwsem, or call this in the constructor of PLNamedMutex, > or tell PLNamedMutext to use the non-default constructor for > m_unamed_semaphore_MemoryMap. To do the last of these the syntax would > be as follows in wxWidgets_comms.cpp > > PLMemoryMap::PLMemoryMap( const char *name, PLINT size, bool > mustExist, bool mustNotExist ) > : m_unamed_semaphore_MemoryMap( use>) > { > The issue with all these potential solutions is PLNamedMutex::create needs access to name, size, etc. for the non-default PLMemoryMap constructor. So it appears that in all cases these solutions of this inter-class communication issue involves passing additional arguments to the PLNamedMutex so the non-default PLMemoryMap constructor can be invoked with the right name, etc. In which case I think the better approach is not to invoke the PLMemoryMap constructor at all from PLNamedMutex and instead pass the wsem address that is determined (correctly according to gdb) from a call to m_outputMemoryMap.getswm() in wxPLDevice::SetupMemoryMap. Anyhow, thanks for your help pointing out the default constructor issue for PLMemoryMap for my present code, and more later about whether the alternative idea of passing the wsem address works out or not. Alan __ Alan W. Irwin Astronomical research affiliation with Department of Physics and Astronomy, University of Victoria (astrowww.phys.uvic.ca). Programming affiliations with the FreeEOS equation-of-state implementation for stellar interiors (freeeos.sf.net); the Time Ephemerides project (timeephem.sf.net); PLplot scientific plotting software package (plplot.sf.net); the libLASi project (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); and the Linux Brochure Project (lbproject.sf.net). __ Linux-powered Science __ -- Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot___ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel
Re: [Plplot-devel] C++ help requested for step 1. (fwd)
On 2017-02-05 21:16- Phil Rosenberg wrote: [...] > As it stands I don't see in your source code where you have called > m_unamed_semaphore_MemoryMap.create( ); > > I think what is happening is that you construct your PLnamedMutex > which constructs all the member variables using their default > constructors (the ones which take no variables). The default > constructor for PLMemoryMap just sets m_buffer to NULL. Your call to > getwsem then takes m_buffer, which is NULL and tries to access some of > it's data and I imagine that is the point that everything goes wrong. > OK. That completely explains my gdb results. All the members of the shmbuf struct appear to well aligned so there is no padding. So the address of wsem (the first member) is exactly the same as the value of m_buffer (the address of the struct) which is NULL according to your above reasoning. And on Linux, sem_t consumes 32 bytes for 64-bit systems and size_t consumes 8 bytes. So buf is offset from the start of the struct by 2*32 + 8 = 72 bytes = 0x48 which is the (bad) gdb result I got for the address of buf. So it appears I am getting consistently wrong results in the PLNamedMutex case for anything to do with PLMemoryMap because of the default constructor used for PLMemoryMap. > Anyway, the fix is to either call m_unamed_semaphore_MemoryMap.create > just before getwsem, or call this in the constructor of PLNamedMutex, > or tell PLNamedMutext to use the non-default constructor for > m_unamed_semaphore_MemoryMap. To do the last of these the syntax would > be as follows in wxWidgets_comms.cpp > > PLMemoryMap::PLMemoryMap( const char *name, PLINT size, bool > mustExist, bool mustNotExist ) > : m_unamed_semaphore_MemoryMap( use>) > { > The issue with all these potential solutions is PLNamedMutex::create needs access to name, size, etc. for the non-default PLMemoryMap constructor. So it appears that in all cases these solutions of this inter-class communication issue involves passing additional arguments to the PLNamedMutex so the non-default PLMemoryMap constructor can be invoked with the right name, etc. In which case I think the better approach is not to invoke the PLMemoryMap constructor at all from PLNamedMutex and instead pass the wsem address that is determined (correctly according to gdb) from a call to m_outputMemoryMap.getswm() in wxPLDevice::SetupMemoryMap. Anyhow, thanks for your help pointing out the default constructor issue for PLMemoryMap for my present code, and more later about whether the alternative idea of passing the wsem address works out or not. Alan __ Alan W. Irwin Astronomical research affiliation with Department of Physics and Astronomy, University of Victoria (astrowww.phys.uvic.ca). Programming affiliations with the FreeEOS equation-of-state implementation for stellar interiors (freeeos.sf.net); the Time Ephemerides project (timeephem.sf.net); PLplot scientific plotting software package (plplot.sf.net); the libLASi project (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); and the Linux Brochure Project (lbproject.sf.net). __ Linux-powered Science __ -- Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot ___ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel
Re: [Plplot-devel] C++ help requested for step 1. (fwd)
Hi Alan Your ears must be burning! (not sure if you have that phrase stateside?) I was just looking through the code and trying to understand the issue. then when I came back to reply I found another email :-) As it stands I don't see in your source code where you have called m_unamed_semaphore_MemoryMap.create( ); I think what is happening is that you construct your PLnamedMutex which constructs all the member variables using their default constructors (the ones which take no variables). The default constructor for PLMemoryMap just sets m_buffer to NULL. Your call to getwsem then takes m_buffer, which is NULL and tries to access some of it's data and I imagine that is the point that everything goes wrong. I think it is actually impossible for your getwsem method to return NULL. Because this function returns the address of member data of m_buffer (which will just be the m_buffer pointer plus a few bytes) then the only way it could return NULL would be if m_buffer was 2^64 minus a few and the memory locations wrapped round - but I'm sure that can't happen. Anyway, the fix is to either call m_unamed_semaphore_MemoryMap.create just before getwsem, or call this in the constructor of PLNamedMutex, or tell PLNamedMutext to use the non-default constructor for m_unamed_semaphore_MemoryMap. To do the last of these the syntax would be as follows in wxWidgets_comms.cpp PLMemoryMap::PLMemoryMap( const char *name, PLINT size, bool mustExist, bool mustNotExist ) : m_unamed_semaphore_MemoryMap() { Hopefully email line breaks haven't messed that up. Just to be clear after the method definition, but before the opening curly bracket ad a colon followed by a comma separated list of all the non default constructors you wish to call. this is called the constructor initialiser list. You would need to add this for each of the constructors of PLMemoryMap and of course you would need to add in your #ifdef statements. I hope this fixes it! Phil On 5 February 2017 at 20:27, Alan W. Irwinwrote: > @everybody (other than Phil who has already been most helpful): > > I would really appreciate some timely help with my C++ questions. > > Although, my (fairly elementary) C++ question below was initially > directed to Phil because he has been kind enough to answer such > questions from me before, if you have some C++ knowledge please don't > be hesitant about jumping in with your own answer to such questions. > After all, Phil is not available 24x7 (in fact he appears not to be > available at the moment) so if you do jump in with the answer, it > should help me reach my wxwidgets development goals much quicker than > if you don't. > > And, by the way, this "jumping in" attitude should be encouraged in > general on this list if you have any relevant knowledge about the > question being discussed. So don't hold back out of some sense of > politeness that you are interrupting someone else's conversation. > > @everybody (including Phil if someone else doesn't beat him to the > answer): > > So to summarize the current status for _everybody_ here, gdb tells me > that calls to m_outputMemoryMap.getBuffer() and > m_outputMemoryMap.getswm() in, wxPLDevice::SetupMemoryMap obtains the > address of the buf char array and wsem in the shared memory shmbuf > struct without issues, and with the expected address 0x48 offset > between the two. However, a few steps later control passes to > PLNamedMutex::create, and the m_unamed_semaphore_MemoryMap version of > those calls produce incorrect addresses (0x48 for the first 0x0 for > the second). So why that difference considering that > m_unamed_semaphore_MemoryMap is defined in a similar way for the > PLNamedMutex class as m_outputMemoryMap is defined for the wxPLDevice > class? > > I feel like I am on the edge of solving this, but I must be missing > something that should be obvious to someone knowledgeable in C++. From > these gdb results I now expect more has to be done than the single statement > > PLMemoryMap m_unamed_semaphore_MemoryMap; > > (see diff below) to set up access to the PLMemoryMap class methods from the > PLNamedMutex class. > > But what is that "more"? > > Alan > __ > Alan W. Irwin > > Astronomical research affiliation with Department of Physics and Astronomy, > University of Victoria (astrowww.phys.uvic.ca). > > Programming affiliations with the FreeEOS equation-of-state > implementation for stellar interiors (freeeos.sf.net); the Time > Ephemerides project (timeephem.sf.net); PLplot scientific plotting > software package (plplot.sf.net); the libLASi project > (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); > and the Linux Brochure Project (lbproject.sf.net). > __ > > Linux-powered Science > __ > > -- Forwarded message -- > Date: Sun, 5 Feb 2017 02:18:28 -0800 (PST) > From: Alan W. Irwin > To: Phil Rosenberg
[Plplot-devel] C++ help requested for step 1. (fwd)
@everybody (other than Phil who has already been most helpful): I would really appreciate some timely help with my C++ questions. Although, my (fairly elementary) C++ question below was initially directed to Phil because he has been kind enough to answer such questions from me before, if you have some C++ knowledge please don't be hesitant about jumping in with your own answer to such questions. After all, Phil is not available 24x7 (in fact he appears not to be available at the moment) so if you do jump in with the answer, it should help me reach my wxwidgets development goals much quicker than if you don't. And, by the way, this "jumping in" attitude should be encouraged in general on this list if you have any relevant knowledge about the question being discussed. So don't hold back out of some sense of politeness that you are interrupting someone else's conversation. @everybody (including Phil if someone else doesn't beat him to the answer): So to summarize the current status for _everybody_ here, gdb tells me that calls to m_outputMemoryMap.getBuffer() and m_outputMemoryMap.getswm() in, wxPLDevice::SetupMemoryMap obtains the address of the buf char array and wsem in the shared memory shmbuf struct without issues, and with the expected address 0x48 offset between the two. However, a few steps later control passes to PLNamedMutex::create, and the m_unamed_semaphore_MemoryMap version of those calls produce incorrect addresses (0x48 for the first 0x0 for the second). So why that difference considering that m_unamed_semaphore_MemoryMap is defined in a similar way for the PLNamedMutex class as m_outputMemoryMap is defined for the wxPLDevice class? I feel like I am on the edge of solving this, but I must be missing something that should be obvious to someone knowledgeable in C++. From these gdb results I now expect more has to be done than the single statement PLMemoryMap m_unamed_semaphore_MemoryMap; (see diff below) to set up access to the PLMemoryMap class methods from the PLNamedMutex class. But what is that "more"? Alan __ Alan W. Irwin Astronomical research affiliation with Department of Physics and Astronomy, University of Victoria (astrowww.phys.uvic.ca). Programming affiliations with the FreeEOS equation-of-state implementation for stellar interiors (freeeos.sf.net); the Time Ephemerides project (timeephem.sf.net); PLplot scientific plotting software package (plplot.sf.net); the libLASi project (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); and the Linux Brochure Project (lbproject.sf.net). __ Linux-powered Science __ -- Forwarded message -- Date: Sun, 5 Feb 2017 02:18:28 -0800 (PST) From: Alan W. IrwinTo: Phil Rosenberg , PLplot development list Subject: [Plplot-devel] C++ help requested for step 1. On 2017-02-04 19:41-0800 Alan W. Irwin wrote: > 1. Make the current one-semaphore approach work with unnamed > semaphores. The last commit put essentially all the infrastructure in > place to support this further change so this change should be a simple > matter of replacing (for this case) the calls to sem_open and > sem_close with sem_init and sem_destroy, and the rest of the current > one-semaphore code should work as is along with the mutex and sleep > API calls required by this method. Hi Phil: I need some help on another C++ issue which should be simple to figure out. I got the first pass at the coding done for (1) (see the diff below relative to current git master), and it builds without issues, but it is not working properly at run time. The problem is (according to gdb) that m_mutex = m_unamed_semaphore_MemoryMap.getwsem(); assigns a NULL pointer to m_mutex which leads to an immediate segfault for the subsequent sem_init(m_mutex, 1, 1); Can you give me the C++ help to figure out why this simple getwsem method is returning a NULL pointer rather than the address of wsem (an unnamed semaphore) within the shared memory struct as intended? Alan diff --git a/drivers/wxwidgets_comms.cpp b/drivers/wxwidgets_comms.cpp index 6b5c071..dfb607c 100644 --- a/drivers/wxwidgets_comms.cpp +++ b/drivers/wxwidgets_comms.cpp @@ -1,4 +1,5 @@ -// Copyright (C) 2015 Phil Rosenberg +// Copyright (C) 2015-2017 Phil Rosenberg +// Copyright (C) 2017 Alan W. Irwin // // This file is part of PLplot. // @@ -171,6 +172,12 @@ void PLNamedMutex::create( const char *name, bool aquireOnCreate ) { #ifdef WIN32 m_mutex = CreateMutexA( NULL, aquireOnCreate ? TRUE : FALSE, name ); +#elif defined(PL_HAVE_UNNAMED_POSIX_SEMAPHORES) +if ( !isValid() ) +{ +m_mutex = m_unamed_semaphore_MemoryMap.getwsem(); +sem_init(m_mutex, 1, 1); +} #else m_mutex = NULL; char mutexName[251]; @@ -232,6 +239,8 @@ void PLNamedMutex::clear()
[Plplot-devel] C++ help requested for step 1.
On 2017-02-04 19:41-0800 Alan W. Irwin wrote: > 1. Make the current one-semaphore approach work with unnamed > semaphores. The last commit put essentially all the infrastructure in > place to support this further change so this change should be a simple > matter of replacing (for this case) the calls to sem_open and > sem_close with sem_init and sem_destroy, and the rest of the current > one-semaphore code should work as is along with the mutex and sleep > API calls required by this method. Hi Phil: I need some help on another C++ issue which should be simple to figure out. I got the first pass at the coding done for (1) (see the diff below relative to current git master), and it builds without issues, but it is not working properly at run time. The problem is (according to gdb) that m_mutex = m_unamed_semaphore_MemoryMap.getwsem(); assigns a NULL pointer to m_mutex which leads to an immediate segfault for the subsequent sem_init(m_mutex, 1, 1); Can you give me the C++ help to figure out why this simple getwsem method is returning a NULL pointer rather than the address of wsem (an unnamed semaphore) within the shared memory struct as intended? Alan diff --git a/drivers/wxwidgets_comms.cpp b/drivers/wxwidgets_comms.cpp index 6b5c071..dfb607c 100644 --- a/drivers/wxwidgets_comms.cpp +++ b/drivers/wxwidgets_comms.cpp @@ -1,4 +1,5 @@ -// Copyright (C) 2015 Phil Rosenberg +// Copyright (C) 2015-2017 Phil Rosenberg +// Copyright (C) 2017 Alan W. Irwin // // This file is part of PLplot. // @@ -171,6 +172,12 @@ void PLNamedMutex::create( const char *name, bool aquireOnCreate ) { #ifdef WIN32 m_mutex = CreateMutexA( NULL, aquireOnCreate ? TRUE : FALSE, name ); +#elif defined(PL_HAVE_UNNAMED_POSIX_SEMAPHORES) +if ( !isValid() ) +{ +m_mutex = m_unamed_semaphore_MemoryMap.getwsem(); +sem_init(m_mutex, 1, 1); +} #else m_mutex = NULL; char mutexName[251]; @@ -232,6 +239,8 @@ void PLNamedMutex::clear() release(); #ifdef WIN32 CloseHandle( m_mutex ); +#elif defined(PL_HAVE_UNNAMED_POSIX_SEMAPHORES) +sem_destroy( m_mutex ); #else sem_close( m_mutex ); #endif diff --git a/drivers/wxwidgets_comms.h b/drivers/wxwidgets_comms.h index a6798ee..90a9be8 100644 --- a/drivers/wxwidgets_comms.h +++ b/drivers/wxwidgets_comms.h @@ -100,6 +100,7 @@ public: bool isValid() { return m_buffer != NULL; } #ifdef PL_HAVE_UNNAMED_POSIX_SEMAPHORES char *getBuffer() { return ( (shmbuf *) m_buffer )->buf; } +sem_t *getwsem() { return & ( ( (shmbuf *) m_buffer )->wsem); } size_t getSize() { return PL_SHARED_ARRAY_SIZE; } #else char *getBuffer() { return (char *) m_buffer; } @@ -134,6 +135,9 @@ private: bool m_haveLock; #ifdef WIN32 HANDLE m_mutex; +#elif defined(PL_HAVE_UNNAMED_POSIX_SEMAPHORES) +PLMemoryMap m_unamed_semaphore_MemoryMap; +sem_t * m_mutex; #else sem_t * m_mutex; #endif __ Alan W. Irwin Astronomical research affiliation with Department of Physics and Astronomy, University of Victoria (astrowww.phys.uvic.ca). Programming affiliations with the FreeEOS equation-of-state implementation for stellar interiors (freeeos.sf.net); the Time Ephemerides project (timeephem.sf.net); PLplot scientific plotting software package (plplot.sf.net); the libLASi project (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net); and the Linux Brochure Project (lbproject.sf.net). __ Linux-powered Science __ -- Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot ___ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel