From: Braden M. <br...@us...> - 2007-04-22 09:09:20
|
Update of /cvsroot/openvrml/openvrml/src/openvrml-xembed In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv20540/src/openvrml-xembed Modified Files: Tag: OpenVRML-0_16-BRANCH gtkvrmlbrowser.cpp Log Message: Ensure that only one thread at a time writes a request to the request channel. Index: gtkvrmlbrowser.cpp =================================================================== RCS file: /cvsroot/openvrml/openvrml/src/openvrml-xembed/gtkvrmlbrowser.cpp,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -C2 -d -r1.1.2.5 -r1.1.2.6 *** gtkvrmlbrowser.cpp 22 Apr 2007 07:13:49 -0000 1.1.2.5 --- gtkvrmlbrowser.cpp 22 Apr 2007 09:09:19 -0000 1.1.2.6 *************** *** 1,3 **** ! // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; -*- // // OpenVRML Mozilla plug-in --- 1,3 ---- ! // -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*- // // OpenVRML Mozilla plug-in *************** *** 100,105 **** --- 100,113 ---- G_GNUC_INTERNAL GdkGLConfig * gl_config; + // + // IMPORTANT: browser::request_channel_mutex_ protects the + // request_channel_ from concurrently running do_get_resource threads. If + // other threads will be using the request_channel concurrently, *you need + // to implement a thread-safe GIOChannel and use that for the + // request_channel*. + // class G_GNUC_INTERNAL browser : public openvrml::browser { GIOChannel * request_channel_; + boost::mutex request_channel_mutex_; public: *************** *** 110,113 **** --- 118,124 ---- virtual std::auto_ptr<openvrml::resource_istream> do_get_resource(const std::string & uri); + + bool write_request_chars(const gchar * buf, gssize count, + gsize * bytes_written); }; *************** *** 544,555 **** class plugin_resource_istream : public openvrml::resource_istream { const boost::shared_ptr<plugin_streambuf> streambuf_; ! GIOChannel * const request_channel_; public: plugin_resource_istream(const std::string & uri, ! GIOChannel * const request_channel): openvrml::resource_istream(0), streambuf_(new plugin_streambuf(uri)), ! request_channel_(request_channel) { using std::ostringstream; --- 555,566 ---- class plugin_resource_istream : public openvrml::resource_istream { const boost::shared_ptr<plugin_streambuf> streambuf_; ! browser & browser_; public: plugin_resource_istream(const std::string & uri, ! browser & b): openvrml::resource_istream(0), streambuf_(new plugin_streambuf(uri)), ! browser_(b) { using std::ostringstream; *************** *** 564,585 **** request << "get-url " << uri << '\n'; gsize bytes_written; ! GError * error = 0; ! scope_guard error_guard = make_guard(g_error_free, ref(error)); ! boost::ignore_unused_variable_warning(error_guard); ! GIOStatus io_status = ! g_io_channel_write_chars(this->request_channel_, ! request.str().data(), ! request.str().length(), ! &bytes_written, ! &error); ! if (io_status != G_IO_STATUS_NORMAL) { ! g_warning(error->message); ! this->setstate(ios_base::badbit); ! return; ! } ! ! io_status = g_io_channel_flush(this->request_channel_, &error); ! if (io_status != G_IO_STATUS_NORMAL) { ! g_warning(error->message); this->setstate(ios_base::badbit); return; --- 575,583 ---- request << "get-url " << uri << '\n'; gsize bytes_written; ! const bool write_succeeded = ! this->browser_.write_request_chars(request.str().data(), ! request.str().length(), ! &bytes_written); ! if (!write_succeeded) { this->setstate(ios_base::badbit); return; *************** *** 593,598 **** this->setstate(ios_base::badbit); } - - error_guard.dismiss(); } --- 591,594 ---- *************** *** 614,618 **** }; return std::auto_ptr<openvrml::resource_istream>( ! new plugin_resource_istream(uri, this->request_channel_)); } --- 610,644 ---- }; return std::auto_ptr<openvrml::resource_istream>( ! new plugin_resource_istream(uri, *this)); ! } ! ! bool browser::write_request_chars(const gchar * const buf, ! const gssize count, ! gsize * const bytes_written) ! { ! boost::mutex::scoped_lock lock(this->request_channel_mutex_); ! ! using boost::ref; ! ! GError * error = 0; ! scope_guard error_guard = make_guard(g_error_free, ref(error)); ! boost::ignore_unused_variable_warning(error_guard); ! ! GIOStatus status = ! g_io_channel_write_chars(this->request_channel_, buf, count, ! bytes_written, &error); ! if (status != G_IO_STATUS_NORMAL) { ! g_warning(error->message); ! return false; ! } ! ! status = g_io_channel_flush(this->request_channel_, &error); ! if (status != G_IO_STATUS_NORMAL) { ! g_warning(error->message); ! return false; ! } ! ! error_guard.dismiss(); ! return true; } |