[Plplot-devel] Recent progress with wxwidgets IPC

2017-02-04 Thread Alan W. Irwin
Hi Phil:

You have probably noticed my recent push of commit 3da0c90.  That
commit contains my recent (fairly small amount of) wxwidgets IPC code
progress.  The unnamed semaphores method requires the shared memory
buffer be a struct (so that the buffer contains room for the required
semaphores as well as the data array).  So all I have done so far is
to adjust the IPC code so it can use a struct for the shared memory,
but at least this commit tests without issues.

N.B. the new IPC code is only exercised if the experimental cmake
option (which defaults to OFF) is set to ON using
-DPL_HAVE_UNNAMED_POSIX_SEMAPHORES=ON.  And conditional compilation
will be used a lot for this development project.  So for the Windows
case the code that is compiled should be completely unaffected by any
of my changes, and for the non-Windows case by default the OLD IPC
method will be preserved and used unless and until the new IPC method
for that case is at least as efficient and reliable as the old one.

So in the ideal case (where all steps below ultimately work and there
are no efficiency reductions due to any of these steps) the remainng
planned steps in this development effort for the
-DPL_HAVE_UNNAMED_POSIX_SEMAPHORES=ON case are as follows:

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.

2. Move from the present one-semaphore approach (which necessarily
includes mutex and sleep activity) to the mutex- and sleep-free
two-semaphore model following the cmake/test_linux_ipc proof-of-concept
project.

3. Implement a two-semaphore version of (2) that uses named semaphores
instead of unnamed semaphores (because not all POSIX systems support
unnamed semaphores).  So this version should differ from 2 only by a
few lines of code (which are already conditionally in place) to use
sem_open and sem_close rather than sem_init and sem_destroy. N.B. like
(2) this approach should also not require any use of mutex or sleep
API.

4. Implement a build system change to test for unnamed semaphore
functionality and use approach (2) if that functionality is available
but otherwise use approach (3).  This should allow us to drop the
present one-semaphore approach that is used in the non-Windows case.

In sum, my work is cut out for me, but at least I have made some initial
progress toward the above goals, and I am beginning to get a bit more
comfortable with C++.

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++ question

2017-02-04 Thread Alan W. Irwin
On 2017-02-05 00:01- Phil Rosenberg wrote:

> It [initialization of private non-const member] should be done in the 
> constructor, so in PlDevice::PlDevice ()

Hi Phil:

That idea makes perfect sense.  However, there was no explicit
constructor for PLDevice. So I had to implement that also, and it was
much tougher than it should have been because the top C++ tutorials
according to google about creating constructors that initialize values
are completely misleading about how to do that (see
 and
).
Using the style they advocated always created multiple
PlDevice::PlDevice symbol definition issues with the linker.  So
instead, I implemented a constructor using a much simpler style that I
guessed at, and it worked (i.e., no compiler warnings no valgrind
memory issues).

But because I guessed, will you please carefully review what I
did (commit d2218b3) to make sure I didn't screw up?

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


[Plplot-devel] C++ question

2017-02-04 Thread Alan W. Irwin
Hi Phil:

What is the proper C++ way to initialize the private non-const member
m_prevSymbol of the PlDevice class to an invalue value (i.e., 0)?
valgrind is complaining about the uninitialized use of m_prevSymbol
for a test in PlDevice::DrawTextLine, and I am looking for a way to
shut it up.  And we want that test to always fail the first time
(hence the need for an assignment to an invalid value) before m_prevSymbol
is assigned a valid value later in the routine.

I tried replacing

PLUNICODE m_prevSymbol;

by

PLUNICODE m_prevSymbol = 0;

in the private area of the PlDevice class defined
in drivers/wxwidgets.h, and that indeed made valgrind
shut up, i.e., the summary line is

ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

but now I have the following compiler warning message:

In file included from 
/home/software/plplot/HEAD/plplot.git/drivers/wxwidgets.cpp:41:0:
/home/software/plplot/HEAD/plplot.git/drivers/wxwidgets.h:103:30: warning: 
non-static data member initializers only available with -std=c++11 or 
-std=gnu++11
  PLUNICODE m_prevSymbol = 0;

I tried using the static attribute for m_prevSymbol, but the compiler errored 
out in
that case because the const attribute was not used.  However, const is
inappropriate because m_prevSymbol does get updated in the above
routine.

So the question boils down to a simple one which is what is the proper
C++ way to initialize a private non-const data member such as
m_prevSymbol without generating compiler warnings or errors?

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] Error propagation

2017-02-04 Thread Phil Rosenberg
Hi Andrew
Thanks for adding to the discussion. Further additions below

On 3 February 2017 at 11:15, Andrew Ross
 wrote:
>
> Hi all,
>
> Sorry I have been silent for so long. Work and life have rather got in
> the way of plplot development. This is something I have raised a couple
> of times in the past and something I have thought about a fair bit.
>
> Comments on Phil's proposals below.
>
> Andrew
>
> On Mon, 2017-01-30 at 11:00 +, Phil Rosenberg wrote:
>> Hi all
>> We have had this discussion in the past. But I would like to reopen
>> it.
>>
>> We really really need to get id of the exit() calls in PLplot. I
>> don't
>> think that we can really make any recommendation that our library is
>> "industrial strength" while they are their and I would be very
>> nervous
>> about using PLplot in production software with them in - plus even
>> using PLplot for science work I have been caught out be these calls
>> in
>> the past.
>>
>> I think there are a few options we have got
>>
>> Firstly with our internal propagation we can either do
>> A1) Set up our functions so they return error codes and make sure we
>> check these. I feel there is a tendency for this to be bad because I
>> know that I am inherently lazy if I am frank (and I'm sure we all
>> have
>> our lazy moments) and tend to write code without these checks then
>> (try to) go back and add them later. Missing checks are likely to
>> cause segfaults or memory corruptions which are even worse than the
>> exit calls().
>
> Laziness is no excuse! The advantage of this proposal is that is allows
> the library to clean things up as we unwind the stack and so (if done
> properly) it will minimise any chance of problems down the line. Even
> if this is a fatal error from plplot's perspective (e.g. memory
> allocation failure), then we must return control to the calling
> programme in a clean and controlled manner.

I wasn't saying it's an excuse, and perhaps I am being flippant using
the term laziness. I guess that what I meant is that it is easy to
forget to do the checking and can be painful, error prone and take a
long time to implement/manage and the result of a single forgotten or
missed error check is equal to a single exit call - i.e. likely
segfault and immediate program termination. Currently a single memory
allocation imposes a single plexit() function call - so at least there
aren't many of them and we know where they are. In a returned error
code solution there will be many function calls to deal with for each
of our current exit calls. Is there a way we can manage this with code
style? Maybe could we label internal functions that can result in
failures with a prefix like plcf (for pl can fail - better prefix
suggestions welcome) Then only functions which have the plcf prefix or
API entry points are allowed to call other functions with the plcf
prefix? Could something like this be checked with a script?
Could we have a required format of checking that we can police with a
script? like if a plcf call is made, the next like should contain if(
err ) or something?

>> A2) Set up an error flag in PLStream which can be set on error and
>> checked after every function call. This would avoid having to change
>> functions that already return values, but still relies on manual
>> checks which I think will be a big weak point.
>
> I would agree that this is still subject to human laziness in checking
> return codes. The advantage of explicitly returning values is that it
> is at least more obvious you need to check them. On the other hand, if
> functions already return values this gets tricky. We probably need to
> do something of a code audit to see if this is likely to be an issue
> before making final decisions.

Same comment as above.
>
>> A3) Use setjmp/longjmp calls. In this case we call setjmp in the top
>> level of every API call and on error we call longjmp which returns
>> the
>> execution point back to the point setjmp was called. There is some
>> extra setup time here to avoid memory leaks and other resource leaks,
>> but once that is done we can all write code with almost no worry
>> regarding error propagation.
>
> This has advantages in terms of not requiring explicit error code
> checking. The bigger problem is making sure we tidy up properly to
> avoid leaks. As Phil says, it requires some care thinking about how we
> deal with non-C drivers as well. I can't say I'm too keen on
> setjmp/longjmp. It can be a lazy solution to the problem rather than
> writing better code in the first place, but given we have a fairly
> large heritage codebase it might be an easier solution.
I don't feel like it is a lazy solution - it is using a feature of the
language for exactly the purpose it was designed for. But I know there
are lots of caveats that come with it. One is that we must do some
book keeping to avoid memory leaks or other resource leaks (like
failure to close files properly). But that bookkeeping seems