Author: wyoung
Date: Wed Nov 28 11:28:06 2007
New Revision: 1917

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1917&view=rev
Log:
Added Connection::thread_aware(), thread_end(), thread_id() and
thread_safe(), and documented all of these in the userman's threading
chapter.

Modified:
    trunk/Wishlist
    trunk/doc/userman/userman.dbx
    trunk/lib/connection.cpp
    trunk/lib/connection.h

Modified: trunk/Wishlist
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=1917&r1=1916&r2=1917&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Wed Nov 28 11:28:06 2007
@@ -23,17 +23,6 @@
     o Apply Jonathan Wakely's patch to RefCountedPointer.
 
     o Atomic inc/dec of reference counts in RefCounted*?
-
-    o Add Connection::thread_start() and thread_end(), wrapping C API.
-      Mention in userman threads chapter that these only need to
-      be called when doing something tricky or linking statically
-      on Windows.  Automatic otherwise.
-
-    o Add Connection::thread_safe(), wrapping mysql_thread_safe() plus
-      maybe also a #defined value set at MySQL++ library build time
-      if thread awareness is enabled.
-
-    o Add Connection::thread_id()
 
     o Add multithreaded examples to test above features and the new
       ConnectionPool class?  They'd have to be platform-specific...

Modified: trunk/doc/userman/userman.dbx
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/userman.dbx?rev=1917&r1=1916&r2=1917&view=diff
==============================================================================
--- trunk/doc/userman/userman.dbx (original)
+++ trunk/doc/userman/userman.dbx Wed Nov 28 11:28:06 2007
@@ -2410,27 +2410,50 @@
 
         <orderedlist>
             <listitem>
-                <para>Build MySQL++ itself with thread awareness turned
-                on. The way you do this depends on your platform,
-                so see the <filename>README</filename> file specific
-                to your platform for further details.</para>
+                <para><emphasis>Build MySQL++ itself with thread
+                awareness turned on.</emphasis></para>
+
+                <para>On platforms that use the
+                <filename>configure</filename> script (Linux, Mac OS X,
+                *BSD, Solaris, Cygwin...) you need to explicitly ask
+                for thread support. And beware, this is only a request
+                to the <filename>configure</filename> script to look
+                for thread support on your system, not a requirement
+                to do or die: if the script doesn't find what it needs
+                to do threading, MySQL++ will just get built without
+                thread support. See <filename>README.unix</filename>
+                for more details.</para>
+
+                <para>When building MySQL++ with the Visual C++
+                project files or the MinGW Makefile that comes with
+                the MySQL++ distribution, threading is always turned
+                on, due to the nature of Windows.</para>
+
+                <para>If you build MySQL++ in some unsupported way,
+                such as with Dev-Cpp (based on MinGW) you're on your
+                own to enable this.</para>
             </listitem>
 
             <listitem>
-                <para>Link your program to a thread-aware build of
-                the MySQL C API library. Depending on your platform,
-                you might have to build this yourself (e.g. Cygwin),
-                or you might get only one library which is always
+                <para><emphasis>Link your program to a thread-aware
+                build of the MySQL C API library.</emphasis></para>
+
+                <para>Depending on your platform, you might
+                have to build this yourself (e.g. Cygwin), or
+                you might get only one library which is always
                 thread-aware (e.g. Visual C++), or there might be
-                two different MySQL C API libraries, one of which is
-                thread-aware and the other not (e.g. Linux). Again,
-                see the <filename>README</filename>s, and also the
-                MySQL developer documentation.</para>
+                two different MySQL C API libraries, one of which
+                is thread-aware and the other not (e.g. Linux). See
+                the <filename>README</filename>.* file for your
+                particular platform, and also the MySQL developer
+                documentation.</para>
             </listitem>
 
             <listitem>
-                <para>Enable thread safety in your program's build
-                options. This is different for every platform, but
+                <para><emphasis>Enable threading in your program's
+                build options.</emphasis></para>
+
+                <para>This is different for every platform, but
                 it's usually the case that you don't get thread-aware
                 builds by default. You might have to turn on a compiler
                 option, or link your program to a different library,
@@ -2514,6 +2537,57 @@
         in MySQL++. The whole point of the library is to make using
         the database easier. We added the pool option for those that
         really need it, but an option it must remain.</para>
+    </sect2>
+
+
+    <sect2>
+        <title>Helper Functions</title>
+
+        <para><classname>Connection</classname> has several
+        thread-related methods you might care about when using MySQL++
+        with threads.</para>
+
+        <para>You can call
+        <methodname>Connection::thread_aware()</methodname> to
+        determine whether MySQL++ and the underlying C API library
+        were both built to be thread-aware. Again, I stress that
+        thread <emphasis>awareness</emphasis> is not the same thing
+        as thread <emphasis>safety</emphasis>: it's still up to you
+        to make your code thread-safe. If this method returns true,
+        it just means it's <emphasis>possible</emphasis> to achieve
+        thread-safety.</para>
+
+        <para>If your program's connection-management strategy
+        allows a thread to use a <classname>Connection</classname>
+        object that another thread created, you must call
+        <methodname>Connection::thread_start()</methodname> from these
+        threads before they do anything with MySQL++. It's safe for
+        the thread that created the <classname>Connection</classname>
+        object to call it, too, but unnecessary. This is because the
+        underlying C API library takes care of it for you when you try
+        to establish your first connection from that thread. So, if you
+        use the simple <classname>Connection</classname>-per-thread
+        strategy lined out above, you never need to call this
+        method, but if you use something more complex like
+        <classname>ConnectionPool</classname>, you do.</para>
+
+        <para>Finally, there's the complementary method,
+        <methodname>Connection::thread_end()</methodname>. Strictly
+        speaking, it's not <emphasis>necessary</emphasis> to
+        call this. However, as alluded above, the underlying C API
+        library allocates some per-thread memory for each thread that
+        calls <methodname>Connection::thread_start()</methodname>
+        or establishes connections. It's not very much memory,
+        it doesn't grow over time, and a typical program is going
+        to need this memory for its entire run time anyway. Memory
+        debuggers aren't smart enough to know all this, though, so
+        they will gripe about a memory leak unless you call this from
+        each thread that uses MySQL++ before that thread exits.</para>
+
+        <para>It's not relevant to this chapter's
+        topic, so to be clear I want to point out that
+        <methodname>Connection::thread_id()</methodname> has to do with
+        threads in the database server, not client-side threads.</para>
     </sect2>
 
 

Modified: trunk/lib/connection.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/connection.cpp?rev=1917&r1=1916&r2=1917&view=diff
==============================================================================
--- trunk/lib/connection.cpp (original)
+++ trunk/lib/connection.cpp Wed Nov 28 11:28:06 2007
@@ -845,5 +845,19 @@
 }
 
 
+bool
+Connection::thread_aware()
+{
+#if defined(MYSQLPP_PLATFORM_WINDOWS) || defined(HAVE_PTHREAD) || 
defined(HAVE_SYNCH_H)
+       // Okay, good, MySQL++ itself is thread-aware, but only return true
+       // if the underlying C API library is also thread-aware.
+       return mysql_thread_safe();
+#else
+       // MySQL++ itself isn't thread-aware, so we don't need to do any
+       // further tests.  All pieces must be thread-aware to return true.
+       return false;   
+#endif
+}
+
 } // end namespace mysqlpp
 

Modified: trunk/lib/connection.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/connection.h?rev=1917&r1=1916&r2=1917&view=diff
==============================================================================
--- trunk/lib/connection.h (original)
+++ trunk/lib/connection.h Wed Nov 28 11:28:06 2007
@@ -298,12 +298,14 @@
 
        /// \brief Kill a MySQL server thread
        ///
-       /// \param pid ID of thread to kill
+       /// \param tid ID of thread to kill
        ///
        /// Simply wraps \c mysql_kill() in the C API.
-       int kill(unsigned long pid)
-       {
-               return mysql_kill(&mysql_, pid);
+    ///
+    /// \see thread_id()
+       int kill(unsigned long tid)
+       {
+               return mysql_kill(&mysql_, tid);
        }
 
        /// \brief Test whether the connection has experienced an error
@@ -475,6 +477,51 @@
        /// and open tables.
        const char* status() { return mysql_stat(&mysql_); }
 
+       /// \brief Returns true if MySQL++ and the underlying MySQL C API
+       /// library were both compiled with thread awareness.
+       ///
+       /// This is based in part on a MySQL C API function
+       /// mysql_thread_safe().  We deliberately don't call this wrapper
+       /// thread_safe() because it's a misleading name: linking to
+       /// thread-aware versions of the MySQL++ and C API libraries doesn't
+       /// automatically make your program "thread-safe".  See the
+       /// <a href="../userman/threads.html">chapter on threads</a> in the
+       /// user manual for more information and guidance.
+       static bool thread_aware();
+
+       /// \brief Tells the underlying MySQL C API library that this thread
+       /// is done using the library.
+       ///
+       /// This exists because the C API library allocates some per-thread
+       /// memory which it doesn't release until you call this.
+       static void thread_end() { mysql_thread_end(); }
+
+       /// \brief Returns the MySQL server thread ID for this connection
+       ///
+       /// This has nothing to do with threading on the client side. It's
+       /// a server-side thread ID, to be used with kill().
+       unsigned long thread_id() { return mysql_thread_id(&mysql_); }
+
+       /// \brief Tells the underlying C API library that the current
+       /// thread will be using the library's services.
+       ///
+       /// \retval True if there was no problem
+       ///
+       /// The MySQL++ user manual's <a href="../userman/threads.html">chapter
+       /// on threads</a> details two major strategies for dealing with
+       /// connections in the face of threads.  If you take the simpler
+       /// path, creating one Connection object per thread, it is never
+       /// necessary to call this function; the underlying C API will call it
+       /// for you when you establish the first database server connection
+       /// from that thread.  If you use a more complex connection
+       /// management strategy where it's possible for one thread to
+       /// establish a connection that another thread uses, you must call
+       /// this from each thread that can use the database before it creates
+       /// any MySQL++ objects.  If you use a ConnectionPool object, this
+       /// applies; ConnectionPool isn't smart enough to call this for you,
+       /// and the C API won't do it, either.
+       static bool thread_start() { return !mysql_thread_init(); }
+
 protected:
        /// \brief Types of option setting errors we can diagnose
        enum OptionError {


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to