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