@Phil: I am particularly interested in your reaction here because you
had the idea before that you could implement PLplot in a thread-safe
way by using C++ as the core language, i.e., rewriting PLplot in C++.
I don't rule out the possibility, but one intermediate step toward
that goal might be to implement the idea below in C, and and then
change our C++ binding so that it automatically uses a PLplotContext
(which would presumably go a long way toward solving your current
issues with PLplot thread safety and wxwidgets).

@Everybody: now on to my C idea for thread safety.

The PLplot core C library is currently not thread safe, and I think we
are all agreed that it is important to address that issue since it is
an important barrier to entry for some. For example, if I recall
correctly it was Ruby on Rails developers who publicly expressed that
they wanted no part of PLplot because of this thread safety issue, and
presumably other library developers are silently avoiding PLplot for
this same reason. In addition, once it becomes possible to use PLplot
in a thread-safe way, it should make life much easier for Phil's
development work on the wxwidgets device.

We would go a long way toward thread safety if we got rid of all
static variables so the rest of this post focuses on that issue from
the C perspective.

My idea for implementing that (closely following what was done for the
C ephcom library case where David Howells implemented an ephcom
context to help provide an API that did not depend on static
variables) is to eliminate all static variables by using a
PLplotContext struct that contains all data that is currently stored
as static variables.

Once that is implemented then the proper non-static way to use PLplot
would be to do something like the following:

PLplotContext * context;

context = CreatePLplotContext();
plparseopts(..., context);
plinit(context);
// other ordinary PLplot calls as usual but with
// context as last argument, e.g.,
plline(..., context);

plend(context);

where CreatePLplotContext would malloc a PLplotContext, and all the
PLplot API calls would refer to that extra context argument whenever
they needed access to any part of what were previously static variables
(e.g., such as plsc).

The context-sensitive plend would do everything that plend currently does plus
destroy the context by freeing it.

So far this follows pretty exactly what David Howells implemented for
ephcom.  Does everybody agree this general idea (a comprehensive API
change where a context argument was added to every function call) would
go a long way toward making PLplot thread safe?

We found in the ephcom case that both the Python and Fortran bindings
for ephcom could pass the C pointer to a context as arguments.  So we
could implement those bindings in a non-static way using the ephcom
equivalent of CreatePLplotContext above. But we retained the static
version of the API just in case some future binding of ephcom was for
a language that could not pass C pointer arguments, and we would also
want to retain the static API for similar reasons in the PLplot case.

For static versions of plinit, plinit variants (e.g., plstar), and/or
all PLplot routines that can legitimately be called before plinit
would call CreatePLplotContext internally if the static variable
PLplotContextAddress was non-NULL and store that pointer in
PLplotContextAddress which would be referenced by every static PLplot
routine (but PLplotContextAddress would be completely ignored by the
non-static API).

For backwards compatibility (e.g., to support those who don't care
about thread safety and who do not want to change their code) we would
want to retain the same name for the static API that are used
now.  But I would like to use the same names for the non-static cases
as well if that is possible (say by following the approach discussed
at <http://stackoverflow.com/questions/1472138/c-default-arguments>.)

Further discussion is encouraged and welcome! Also, I am well aware I
have glossed over lots of details here.  That is because I frankly
don't completely understand all those details!  :-) Nevertheless,
assuming I have expressed the overview correctly of what would be
required, I hope someone will be inspired by that overview to go ahead
and implement the non-static C alternative as a very large step toward
the ability to use our library in a thread-safe way.

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: Tue, 10 Dec 2002 02:52:43 -0600 (CST)
From: Maurice LeBrun <m...@gazoo.ph.utexas.edu>
To: Alan W. Irwin <ir...@beluga.phys.uvic.ca>
Cc: PLplot development list <Plplot-devel@lists.sourceforge.net>
Subject: Re: [Plplot-devel] plinit, plend, plinit sequence now works,
     but I am having second thoughts

I can't tell you the specific answer to your questions due to how maniacally
busy I am these days (having just joined Lightspeed Semiconductor), but I can
elucidate some of the plplot design ideas that have historically been
un-documented.  And, I can give it in an object-oriented context, which
(because it is "canonical") is a lot nicer than the "this is the way it should
work" approach I've used historically. :)

This also includes proposals for change to how we do it now -- i.e. the
behavior of plinit().  I've always been somewhat bothered by the way stream 0
vs stream N is handled (this bugged me back in '94 but I wasn't exactly
swimming in free time then either).

When plplot starts, you have the statically pre-allocated stream, stream 0.
Yes the stream 0 that I hate b/c it's not allocated on the heap like a proper
data-structure/object (in the plframe widget I automatically start from stream
1).

So stream 0 is like a class definition and an instance rolled into one.  What
I think we need to do is get rid of the "instance" part of this and leave
stream 0 as a "class definition" only.  In this case all the command line
arguments and initial pls...() calls (before plinit) serve to override the
default initializion of the class variables, i.e. set stream 0 parameters only

In other words, stream 0 becomes the template for all plplot streams.  You can
use it, but once you've called plinit() you have your own "instance" of the
plplot "object" -- i.e. you have a new stream with all the relevant state info
copied from stream 0.  If you change it, it dies when your stream dies with
plend1().

If you really want to change stream 0 (i.e. the "plplot object" "class data")
you can always set your stream number to 0 and fire away.

To summarize:

plinit() creates a new stream, copied from stream 0
plend1() deletes that stream
plend() deletes all streams, except of course stream 0 which is "class data"

Let me know if any of this helps.

-- 
Maurice LeBrun    m...@gazoo.ph.utexas.edu
Research Organization for Information Science and Technology of Japan (RIST)

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to