@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