void IpcMsg::run() { auto sem = new QSystemSemaphore( "TimeTrackSem", 0, QSystemSemaphore::Create); while(true){ sem->acquire(); // blocks until message arrives // read message from shared memery QString msg; QTextStream stream(&msg); const char *from = (char const*)shmMaster->data(); while(from && *from){ stream << *from; ++from; } // send message to main thread emit incomingMsg(msg); // if message is "exit", break loop if(msg == "exit"){ break; } } // cleanup on exit delete sem; }
Telegram::Telegram(int argc, char **argv, QObject *parent) : QObject(parent) { p = new TelegramPrivate; p->update_dialog_again = false; p->update_dialog_timer_id = 0; p->update_contact_again = false; p->update_contact_timer_id = 0; p->authenticating = false; p->started = false; p->msg_send_timer = 0; p->last_wait_and_get = Enums::NoWaitAndGet; p->tg_thread = new TelegramThread(argc,argv); connect( p->tg_thread, SIGNAL(contactsChanged()) , SIGNAL(meChanged()) ); connect( p->tg_thread, SIGNAL(contactsChanged()) , SLOT(_loadOwnInfo()) ); connect( p->tg_thread, SIGNAL(unreadChanged()) , SIGNAL(unreadChanged()) ); connect( p->tg_thread, SIGNAL(contactsChanged()) , SIGNAL(contactsChanged()) ); connect( p->tg_thread, SIGNAL(dialogsChanged()) , SIGNAL(dialogsChanged()) ); connect( p->tg_thread, SIGNAL(incomingMsg(qint64)) , SIGNAL(incomingMsg(qint64)) ); connect( p->tg_thread, SIGNAL(incomingNewMsg(qint64)) , SLOT(_incomingNewMsg(qint64)) ); connect( p->tg_thread, SIGNAL(userIsTyping(int,int)) , SIGNAL(userIsTyping(int,int)) ); connect( p->tg_thread, SIGNAL(userStatusChanged(int,int,QDateTime)), SIGNAL(userStatusChanged(int,int,QDateTime)) ); connect( p->tg_thread, SIGNAL(msgChanged(qint64)) , SIGNAL(msgChanged(qint64)) ); connect( p->tg_thread, SIGNAL(msgSent(qint64,qint64)) , SIGNAL(msgSent(qint64,qint64)) ); connect( p->tg_thread, SIGNAL(userPhotoChanged(int)) , SIGNAL(userPhotoChanged(int)) ); connect( p->tg_thread, SIGNAL(chatPhotoChanged(int)) , SIGNAL(chatPhotoChanged(int)) ); connect( p->tg_thread, SIGNAL(fileUploaded(int,QString)) , SIGNAL(fileUploaded(int,QString)) ); connect( p->tg_thread, SIGNAL(fileUploading(int,QString,qreal)) , SIGNAL(fileUploading(int,QString,qreal)) ); connect( p->tg_thread, SIGNAL(fileUserUploaded(int)) , SIGNAL(fileUserUploaded(int)) ); connect( p->tg_thread, SIGNAL(fileUserUploading(int,qreal)) , SIGNAL(fileUserUploading(int,qreal)) ); connect( p->tg_thread, SIGNAL(msgFileDownloaded(qint64)) , SIGNAL(msgFileDownloaded(qint64)) ); connect( p->tg_thread, SIGNAL(msgFileDownloading(qint64,qreal)) , SIGNAL(msgFileDownloading(qint64,qreal)) ); connect( p->tg_thread, SIGNAL(messageDeleted(qint64)) , SIGNAL(messageDeleted(qint64)) ); connect( p->tg_thread, SIGNAL(messageRestored(qint64)) , SIGNAL(messageRestored(qint64)) ); connect( p->tg_thread, SIGNAL(registeringStarted()) , SLOT(registeringStarted()) ); connect( p->tg_thread, SIGNAL(registeringFinished()) , SLOT(registeringFinished()) ); connect( p->tg_thread, SIGNAL(registeringInvalidCode()) , SIGNAL(registeringInvalidCode()) ); connect( p->tg_thread, SIGNAL(myStatusUpdated()) , SIGNAL(myStatusUpdated()) ); connect( p->tg_thread, SIGNAL(waitAndGet(int)) , SLOT(_waitAndGet(int)) ); connect( p->tg_thread, SIGNAL(tgStarted()) , SLOT(_startedChanged()) ); p->tg_thread->start(); }
static Iface_DEFUN incomingMsg(struct Message* msg, struct Pathfinder_pvt* pf) { struct Address addr; struct RouteHeader* hdr = (struct RouteHeader*) msg->bytes; Message_shift(msg, -(RouteHeader_SIZE + DataHeader_SIZE), NULL); Bits_memcpy(addr.ip6.bytes, hdr->ip6, 16); Bits_memcpy(addr.key, hdr->publicKey, 32); addr.protocolVersion = Endian_bigEndianToHost32(hdr->version_be); addr.padding = 0; addr.path = Endian_bigEndianToHost64(hdr->sh.label_be); //Log_debug(pf->log, "Incoming DHT"); struct DHTMessage dht = { .address = &addr, .binMessage = msg, .allocator = msg->alloc }; DHTModuleRegistry_handleIncoming(&dht, pf->registry); struct Message* nodeMsg = Message_new(0, 256, msg->alloc); Iface_CALL(sendNode, nodeMsg, &addr, 0xfffffff0u, pf); if (dht.pleaseRespond) { // what a beautiful hack, see incomingFromDHT return Iface_next(&pf->pub.eventIf, msg); } return NULL; } static Iface_DEFUN incomingFromEventIf(struct Message* msg, struct Iface* eventIf) { struct Pathfinder_pvt* pf = Identity_containerOf(eventIf, struct Pathfinder_pvt, pub.eventIf); enum PFChan_Core ev = Message_pop32(msg, NULL); if (Pathfinder_pvt_state_INITIALIZING == pf->state) { Assert_true(ev == PFChan_Core_CONNECT); return connected(pf, msg); } // Let the PF send another 128 path changes again because it's basically a new tick. pf->bestPathChanges = 0; switch (ev) { case PFChan_Core_SWITCH_ERR: return switchErr(msg, pf); case PFChan_Core_SEARCH_REQ: return searchReq(msg, pf); case PFChan_Core_PEER: return peer(msg, pf); case PFChan_Core_PEER_GONE: return peerGone(msg, pf); case PFChan_Core_SESSION: return session(msg, pf); case PFChan_Core_SESSION_ENDED: return sessionEnded(msg, pf); case PFChan_Core_DISCOVERED_PATH: return discoveredPath(msg, pf); case PFChan_Core_MSG: return incomingMsg(msg, pf); case PFChan_Core_PING: return handlePing(msg, pf); case PFChan_Core_PONG: return handlePong(msg, pf); case PFChan_Core_UNSETUP_SESSION: case PFChan_Core_LINK_STATE: case PFChan_Core_CTRL_MSG: return NULL; default:; } Assert_failure("unexpected event [%d]", ev); } static void sendEvent(struct Pathfinder_pvt* pf, enum PFChan_Pathfinder ev, void* data, int size) { struct Allocator* alloc = Allocator_child(pf->alloc); struct Message* msg = Message_new(0, 512+size, alloc); Message_push(msg, data, size, NULL); Message_push32(msg, ev, NULL); Iface_send(&pf->pub.eventIf, msg); Allocator_free(alloc); } static void init(void* vpf) { struct Pathfinder_pvt* pf = Identity_check((struct Pathfinder_pvt*) vpf); struct PFChan_Pathfinder_Connect conn = { .superiority_be = Endian_hostToBigEndian32(1), .version_be = Endian_hostToBigEndian32(Version_CURRENT_PROTOCOL) }; CString_strncpy(conn.userAgent, "Cjdns internal pathfinder", 64); sendEvent(pf, PFChan_Pathfinder_CONNECT, &conn, PFChan_Pathfinder_Connect_SIZE); } struct Pathfinder* Pathfinder_register(struct Allocator* allocator, struct Log* log, struct EventBase* base, struct Random* rand, struct Admin* admin) { struct Allocator* alloc = Allocator_child(allocator); struct Pathfinder_pvt* pf = Allocator_calloc(alloc, sizeof(struct Pathfinder_pvt), 1); Identity_set(pf); pf->alloc = alloc; pf->log = log; pf->base = base; pf->rand = rand; pf->admin = admin; pf->pub.eventIf.send = incomingFromEventIf; pf->dhtModule.context = pf; pf->dhtModule.handleOutgoing = incomingFromDHT; // This needs to be done asynchronously so the pf can be plumbed to the core Timeout_setTimeout(init, pf, 0, base, alloc); return &pf->pub; }