2012-02-07 17:28:30 +01:00
// Copyright (c) 2009-2012 The Bitcoin developers
2011-12-24 05:27:12 +01:00
// Distributed under the MIT/X11 software license, see the accompanying
2012-07-22 23:49:09 +02:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2011-12-24 05:27:12 +01:00
2012-08-24 03:47:02 +02:00
# include <boost/version.hpp>
# if defined(WIN32) && BOOST_VERSION == 104900
# define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
# define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
# endif
2012-07-06 13:45:38 +02:00
# include "qtipcserver.h"
# include "guiconstants.h"
# include "ui_interface.h"
# include "util.h"
2012-08-24 18:48:41 +02:00
# include <boost/algorithm/string/predicate.hpp>
2011-12-24 05:27:12 +01:00
# include <boost/date_time/posix_time/posix_time.hpp>
2012-07-06 13:45:38 +02:00
# include <boost/interprocess/ipc/message_queue.hpp>
2012-03-25 22:17:39 +02:00
# include <boost/version.hpp>
# if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900)
# warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost / interprocess / detail / tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org / trac / boost / ticket / 5392
# endif
2011-12-24 05:27:12 +01:00
2012-07-06 13:45:38 +02:00
using namespace boost ;
2011-12-24 05:27:12 +01:00
using namespace boost : : interprocess ;
using namespace boost : : posix_time ;
2012-07-06 13:45:38 +02:00
Fix Qt build on OSX
Compiling boost::interprocess::message_queue against
boost 1.50 macports with -arch i386 (how releases are built,
for minimum download size and maximum compatibility) is failing:
src/qt/qtipcserver.cpp:37: error: no matching function for call to ‘boost::interprocess::message_queue_t<boost::interprocess::offset_ptr<void, int, long unsigned int, 0u> >::timed_receive(char (*)[257], long unsigned int, size_t&, unsigned int&, boost::posix_time::ptime&)’
This is probably a boost or macports bug, but since interprocess::message_queue
is only used for URI support, which isn't implemented on OSX anyway, I fixed
the build by #ifdef'ing out that code.
2012-07-09 17:03:38 +02:00
# ifdef MAC_OSX
// URI handling not implemented on OSX yet
2012-08-24 18:48:41 +02:00
void ipcScanRelay ( int argc , char * argv [ ] ) { }
void ipcInit ( int argc , char * argv [ ] ) { }
Fix Qt build on OSX
Compiling boost::interprocess::message_queue against
boost 1.50 macports with -arch i386 (how releases are built,
for minimum download size and maximum compatibility) is failing:
src/qt/qtipcserver.cpp:37: error: no matching function for call to ‘boost::interprocess::message_queue_t<boost::interprocess::offset_ptr<void, int, long unsigned int, 0u> >::timed_receive(char (*)[257], long unsigned int, size_t&, unsigned int&, boost::posix_time::ptime&)’
This is probably a boost or macports bug, but since interprocess::message_queue
is only used for URI support, which isn't implemented on OSX anyway, I fixed
the build by #ifdef'ing out that code.
2012-07-09 17:03:38 +02:00
# else
2012-08-27 18:37:35 +02:00
static void ipcThread2 ( void * pArg ) ;
2012-08-24 18:48:41 +02:00
static bool ipcScanCmd ( int argc , char * argv [ ] , bool fRelay )
{
// Check for URI in argv
bool fSent = false ;
for ( int i = 1 ; i < argc ; i + + )
{
if ( boost : : algorithm : : istarts_with ( argv [ i ] , " bitcoin: " ) )
{
const char * strURI = argv [ i ] ;
try {
boost : : interprocess : : message_queue mq ( boost : : interprocess : : open_only , BITCOINURI_QUEUE_NAME ) ;
if ( mq . try_send ( strURI , strlen ( strURI ) , 0 ) )
fSent = true ;
else if ( fRelay )
break ;
}
catch ( boost : : interprocess : : interprocess_exception & ex ) {
// don't log the "file not found" exception, because that's normal for
// the first start of the first instance
if ( ex . get_error_code ( ) ! = boost : : interprocess : : not_found_error | | ! fRelay )
{
printf ( " main() - boost interprocess exception #%d: %s \n " , ex . get_error_code ( ) , ex . what ( ) ) ;
break ;
}
}
}
}
return fSent ;
}
void ipcScanRelay ( int argc , char * argv [ ] )
{
if ( ipcScanCmd ( argc , argv , true ) )
exit ( 0 ) ;
}
2012-07-06 13:45:38 +02:00
static void ipcThread ( void * pArg )
2011-12-24 05:27:12 +01:00
{
2012-07-06 13:45:38 +02:00
// Make this thread recognisable as the GUI-IPC thread
RenameThread ( " bitcoin-gui-ipc " ) ;
try
{
ipcThread2 ( pArg ) ;
}
catch ( std : : exception & e ) {
PrintExceptionContinue ( & e , " ipcThread() " ) ;
} catch ( . . . ) {
PrintExceptionContinue ( NULL , " ipcThread() " ) ;
}
printf ( " ipcThread exited \n " ) ;
2011-12-24 05:27:12 +01:00
}
2012-07-06 13:45:38 +02:00
static void ipcThread2 ( void * pArg )
2011-12-24 05:27:12 +01:00
{
2012-07-06 13:45:38 +02:00
printf ( " ipcThread started \n " ) ;
message_queue * mq = ( message_queue * ) pArg ;
char buffer [ MAX_URI_LENGTH + 1 ] = " " ;
size_t nSize = 0 ;
unsigned int nPriority = 0 ;
2012-07-08 23:22:08 +02:00
2011-12-24 05:27:12 +01:00
loop
{
ptime d = boost : : posix_time : : microsec_clock : : universal_time ( ) + millisec ( 100 ) ;
2012-07-06 13:45:38 +02:00
if ( mq - > timed_receive ( & buffer , sizeof ( buffer ) , nSize , nPriority , d ) )
2011-12-24 05:27:12 +01:00
{
2012-07-06 13:45:38 +02:00
uiInterface . ThreadSafeHandleURI ( std : : string ( buffer , nSize ) ) ;
2011-12-24 05:27:12 +01:00
Sleep ( 1000 ) ;
}
2012-07-06 13:45:38 +02:00
2011-12-24 05:27:12 +01:00
if ( fShutdown )
break ;
}
2012-07-06 13:45:38 +02:00
// Remove message queue
message_queue : : remove ( BITCOINURI_QUEUE_NAME ) ;
// Cleanup allocated memory
delete mq ;
2011-12-24 05:27:12 +01:00
}
2012-08-24 18:48:41 +02:00
void ipcInit ( int argc , char * argv [ ] )
2011-12-24 05:27:12 +01:00
{
2012-07-06 13:45:38 +02:00
message_queue * mq = NULL ;
char buffer [ MAX_URI_LENGTH + 1 ] = " " ;
size_t nSize = 0 ;
unsigned int nPriority = 0 ;
2011-12-24 05:27:12 +01:00
try {
2012-07-06 13:45:38 +02:00
mq = new message_queue ( open_or_create , BITCOINURI_QUEUE_NAME , 2 , MAX_URI_LENGTH ) ;
2011-12-24 05:27:12 +01:00
// Make sure we don't lose any bitcoin: URIs
for ( int i = 0 ; i < 2 ; i + + )
{
ptime d = boost : : posix_time : : microsec_clock : : universal_time ( ) + millisec ( 1 ) ;
2012-07-06 13:45:38 +02:00
if ( mq - > timed_receive ( & buffer , sizeof ( buffer ) , nSize , nPriority , d ) )
2011-12-24 05:27:12 +01:00
{
2012-07-06 13:45:38 +02:00
uiInterface . ThreadSafeHandleURI ( std : : string ( buffer , nSize ) ) ;
2011-12-24 05:27:12 +01:00
}
else
break ;
}
// Make sure only one bitcoin instance is listening
2012-03-25 23:25:10 +02:00
message_queue : : remove ( BITCOINURI_QUEUE_NAME ) ;
2012-07-06 13:45:38 +02:00
delete mq ;
mq = new message_queue ( open_or_create , BITCOINURI_QUEUE_NAME , 2 , MAX_URI_LENGTH ) ;
2011-12-24 05:27:12 +01:00
}
catch ( interprocess_exception & ex ) {
2012-07-06 13:45:38 +02:00
printf ( " ipcInit() - boost interprocess exception #%d: %s \n " , ex . get_error_code ( ) , ex . what ( ) ) ;
2011-12-24 05:27:12 +01:00
return ;
}
2012-07-06 13:45:38 +02:00
2012-08-29 20:25:37 +02:00
if ( ! NewThread ( ipcThread , mq ) )
2011-12-24 05:27:12 +01:00
{
delete mq ;
2012-07-06 13:45:38 +02:00
return ;
2011-12-24 05:27:12 +01:00
}
2012-08-24 18:48:41 +02:00
ipcScanCmd ( argc , argv , false ) ;
2011-12-24 05:27:12 +01:00
}
Fix Qt build on OSX
Compiling boost::interprocess::message_queue against
boost 1.50 macports with -arch i386 (how releases are built,
for minimum download size and maximum compatibility) is failing:
src/qt/qtipcserver.cpp:37: error: no matching function for call to ‘boost::interprocess::message_queue_t<boost::interprocess::offset_ptr<void, int, long unsigned int, 0u> >::timed_receive(char (*)[257], long unsigned int, size_t&, unsigned int&, boost::posix_time::ptime&)’
This is probably a boost or macports bug, but since interprocess::message_queue
is only used for URI support, which isn't implemented on OSX anyway, I fixed
the build by #ifdef'ing out that code.
2012-07-09 17:03:38 +02:00
# endif