123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- // ECOin - Copyright (c) - 2014/2021 - GPLv3 - epsylon@riseup.net (https://03c8.net)
- #include <boost/version.hpp>
- #if defined(WIN32) && BOOST_VERSION == 104900
- #define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
- #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
- #endif
- #include "qtipcserver.h"
- #include "guiconstants.h"
- #include "ui_interface.h"
- #include "util.h"
- #include <boost/algorithm/string/predicate.hpp>
- #include <boost/date_time/posix_time/posix_time.hpp>
- #include <boost/interprocess/ipc/message_queue.hpp>
- #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
- using namespace boost;
- using namespace boost::interprocess;
- using namespace boost::posix_time;
- #if defined MAC_OSX || defined __FreeBSD__
- // URI handling not implemented on OSX yet
- void ipcScanRelay(int argc, char *argv[]) { }
- void ipcInit(int argc, char *argv[]) { }
- #else
- static void ipcThread2(void* pArg);
- 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], "ecoin:"))
- {
- const char *strURI = argv[i];
- try {
- boost::interprocess::message_queue mq(boost::interprocess::open_only, ECOINURI_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);
- }
- static void ipcThread(void* pArg)
- {
- // Make this thread recognisable as the GUI-IPC thread
- RenameThread("ecoin-gui-ipc");
-
- try
- {
- ipcThread2(pArg);
- }
- catch (std::exception& e) {
- PrintExceptionContinue(&e, "ipcThread()");
- } catch (...) {
- PrintExceptionContinue(NULL, "ipcThread()");
- }
- printf("ipcThread exited\n");
- }
- static void ipcThread2(void* pArg)
- {
- printf("ipcThread started\n");
- message_queue* mq = (message_queue*)pArg;
- char buffer[MAX_URI_LENGTH + 1] = "";
- size_t nSize = 0;
- unsigned int nPriority = 0;
- while (true)
- {
- ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
- if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
- {
- uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
- Sleep(1000);
- }
- if (fShutdown)
- break;
- }
- // Remove message queue
- message_queue::remove(ECOINURI_QUEUE_NAME);
- // Cleanup allocated memory
- delete mq;
- }
- void ipcInit(int argc, char *argv[])
- {
- message_queue* mq = NULL;
- char buffer[MAX_URI_LENGTH + 1] = "";
- size_t nSize = 0;
- unsigned int nPriority = 0;
- try {
- mq = new message_queue(open_or_create, ECOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
- // Make sure we don't lose any ecoin: URIs
- for (int i = 0; i < 2; i++)
- {
- ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
- if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
- {
- uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
- }
- else
- break;
- }
- // Make sure only one ecoin instance is listening
- message_queue::remove(ECOINURI_QUEUE_NAME);
- delete mq;
- mq = new message_queue(open_or_create, ECOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
- }
- catch (interprocess_exception &ex) {
- printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
- return;
- }
- if (!NewThread(ipcThread, mq))
- {
- delete mq;
- return;
- }
- ipcScanCmd(argc, argv, false);
- }
- #endif
|