Changeset 5975 for branches/newapi
- Timestamp:
- 01/01/08 20:28:13 (11 months ago)
- Location:
- branches/newapi/licq
- Files:
-
- 6 modified
-
licq/event/eventqueue.h (modified) (4 diffs)
-
src/event/eventqueue.cpp (modified) (5 diffs)
-
src/event/eventqueue.h (modified) (2 diffs)
-
src/event/test/eventqueuetest.cpp (modified) (2 diffs)
-
src/plugin/plugininstanceimpl.cpp (modified) (1 diff)
-
src/plugin/pluginmanagerimpl.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/newapi/licq/licq/event/eventqueue.h
r5952 r5975 1 1 /* 2 2 * This file is part of Licq, an instant messaging client for UNIX. 3 * Copyright (C) 2007 Erik Johansson <erijo@licq.org>3 * Copyright (C) 2007-2008 Erik Johansson <erijo@licq.org> 4 4 * 5 5 * Licq is free software; you can redistribute it and/or modify … … 28 28 { 29 29 30 /** 31 * EventQueue is a thread-safe producer-consumer queue. The 32 * producer(s) pushes events to the queue with push(). The consumer 33 * notices that the file descriptor returned from getFileDescriptor() 34 * is ready for reading and reads one or more bytes. For each byte 35 * read, it calls pop(), handles the event, and then passes the event 36 * on. 37 * 38 * @threadsafe 39 */ 30 40 class EventQueue : private boost::noncopyable 31 41 { … … 36 46 * be available for reading. 37 47 * 38 * @returns The read file descriptor .48 * @returns The read file descriptor, configured to be non-blocking. 39 49 */ 40 50 virtual int getFileDescriptor() const = 0; … … 46 56 47 57 /** 48 * Pushes an event to the end of the queue. The queue takes 49 * ownership of the event and @a event is reset before the function 50 * returns. 58 * Pushes an event to the end of the queue. Once an event has been 59 * pushed to the queue, it should not be used again by the caller, 60 * since another thread may already be using it. 61 * 62 * @param event The event to add to the queue. 51 63 */ 52 virtual void push Event(boost::shared_ptr<Event>&event) = 0;64 virtual void push(boost::shared_ptr<Event> event) = 0; 53 65 54 66 /** 55 * @returns The event in the front of the queue. 67 * Removes the first event from the queue and returns it. 68 * 69 * @returns The first event in the queue. 56 70 * @throws Licq::RuntimeException If the queue is empty. 57 71 */ 58 virtual boost::shared_ptr<Event> getEvent() const = 0; 59 60 /** 61 * Commit the event in front of the queue. Before committing, make 62 * sure that no reference to any Event returned from getEvent() 63 * remains. This may include calling boost::shared_ptr::reset(). 64 * 65 * @throws Licq::RuntimeException If the queue is empty. 66 */ 67 virtual void commitEvent() = 0; 72 virtual boost::shared_ptr<Event> pop() = 0; 68 73 69 74 protected: -
branches/newapi/licq/src/event/eventqueue.cpp
r5952 r5975 25 25 #include <cassert> 26 26 27 LicqDaemon::EventQueue::EventQueue(const std::string& name , EventManager* manager)27 LicqDaemon::EventQueue::EventQueue(const std::string& name) 28 28 : myName(name), 29 myEventManager(manager),30 29 myQueueMutex(name), 31 30 myPipe(name) 32 31 { 33 assert(myEventManager != NULL);34 35 32 myPipe.setBlockingRead(false); 36 33 myPipe.setBlockingWrite(true); … … 39 36 LicqDaemon::EventQueue::~EventQueue() 40 37 { 41 Licq::MutexLocker locker(&myQueueMutex); 42 while (!myQueue.empty()) 43 commitEventInternal(); 38 assert(empty()); 44 39 } 45 40 … … 55 50 } 56 51 57 void LicqDaemon::EventQueue::push Event(boost::shared_ptr<Licq::Event>&event)52 void LicqDaemon::EventQueue::push(boost::shared_ptr<Licq::Event> event) 58 53 { 59 // Take ownership of event60 boost::shared_ptr<Licq::Event> newEvent;61 newEvent.swap(event);62 assert(newEvent.unique());63 64 54 // Add to queue 65 55 Licq::MutexLocker locker(&myQueueMutex); 66 myQueue.push( newEvent);56 myQueue.push(event); 67 57 68 58 // Notify … … 70 60 } 71 61 72 boost::shared_ptr<Licq::Event> LicqDaemon::EventQueue:: getEvent() const62 boost::shared_ptr<Licq::Event> LicqDaemon::EventQueue::pop() 73 63 { 74 64 Licq::MutexLocker locker(&myQueueMutex); … … 76 66 throw Licq::RuntimeException(tr("EventQueue %1% is empty") % myName); 77 67 78 return myQueue.front();79 }80 81 void LicqDaemon::EventQueue::commitEvent()82 {83 Licq::MutexLocker locker(&myQueueMutex);84 if (myQueue.empty())85 throw Licq::RuntimeException(tr("EventQueue %1% is empty") % myName);86 87 commitEventInternal();88 }89 90 void LicqDaemon::EventQueue::commitEventInternal()91 {92 68 boost::shared_ptr<Licq::Event> event = myQueue.front(); 93 69 myQueue.pop(); 94 95 myEventManager->sendEvent(event); 70 return event; 96 71 } -
branches/newapi/licq/src/event/eventqueue.h
r5952 r5975 23 23 #include "licq/event/eventqueue.h" 24 24 #include "licq/thread/mutex.h" 25 #include "event/eventmanager.h"26 25 #include "util/pipe.h" 27 26 … … 34 33 { 35 34 public: 36 EventQueue(const std::string& name , EventManager* manager);35 EventQueue(const std::string& name); 37 36 ~EventQueue(); 38 37 39 38 // From Licq::EventQueue 40 39 int getFileDescriptor() const; 41 void pushEvent(boost::shared_ptr<Licq::Event>& event);42 40 bool empty() const; 43 boost::shared_ptr<Licq::Event> getEvent() const;44 void commitEvent();41 void push(boost::shared_ptr<Licq::Event> event); 42 boost::shared_ptr<Licq::Event> pop(); 45 43 46 44 private: 47 void commitEventInternal(); 45 typedef std::queue< boost::shared_ptr<Licq::Event> > Queue; 46 Queue myQueue; 48 47 49 48 const std::string myName; 50 EventManager* myEventManager;51 52 typedef std::queue< boost::shared_ptr<Licq::Event> > Queue;53 Queue myQueue;54 49 mutable Licq::Mutex myQueueMutex; 55 56 50 Pipe myPipe; 57 51 }; -
branches/newapi/licq/src/event/test/eventqueuetest.cpp
r5952 r5975 18 18 */ 19 19 20 #include "event/eventmanager.h"21 20 #include "event/eventqueue.h" 22 #include " test/recorder.h"21 #include "licq/exception/runtimeexception.h" 23 22 24 23 #include <boost/test/unit_test.hpp> 25 #include <cassert>26 24 27 struct EventQueueFixture : public LicqDaemon::EventManager25 struct EventQueueFixture 28 26 { 29 void reset()27 ssize_t read(Licq::EventQueue* queue) 30 28 { 31 BOOST_REQUIRE(recorder.isEmpty()); 29 int fd = queue->getFileDescriptor(); 30 31 char buffer[16]; 32 return ::read(fd, &buffer, sizeof(buffer)); 32 33 } 33 34 // EventManager35 void registerQueue(const std::string&, Licq::EventQueue*, int)36 {37 assert(false);38 }39 40 void unregisterQueue(const std::string&, Licq::EventQueue*)41 {42 assert(false);43 }44 45 void unregisterQueue(Licq::EventQueue*)46 {47 assert(false);48 }49 50 void sendEvent(boost::shared_ptr<Licq::Event>& event)51 {52 recorder.push(boost::format("sendEvent(%1%)") % event->getId());53 }54 55 LicqTest::Recorder recorder;56 34 }; 57 35 … … 60 38 BOOST_AUTO_TEST_CASE(basic) 61 39 { 62 reset(); 40 const size_t count = 5; 41 boost::shared_ptr<Licq::Event> event[count]; 42 Licq::Event::Id id[count]; 63 43 64 LicqDaemon::EventQueue queue("test", this); 65 boost::shared_ptr<Licq::Event> test = Licq::Event::create("test"); 66 Licq::Event* testPtr = test.get(); 67 Licq::Event::Id id = test->getId(); 44 // Setup some events 45 for (size_t i = 0; i < count; i++) 46 { 47 event[i] = Licq::Event::create("test"); 48 id[i] = event[i]->getId(); 49 event[i]->setProperty("42 * i", (int)(42 * i)); 50 } 68 51 69 queue.pushEvent(test); 70 BOOST_CHECK_EQUAL(queue.empty(), false); 52 boost::shared_ptr<Licq::Event> temp; 71 53 72 // Adding an event should invalidate the pointer73 BOOST_CHECK _EQUAL(test.get(), (Licq::Event*)NULL);54 LicqDaemon::EventQueue queue("testqueue"); 55 BOOST_CHECK(queue.empty()); 74 56 75 BOOST_CHECK_EQUAL(queue.getEvent().get(), testPtr);76 queue.commitEvent();77 BOOST_CHECK_EQUAL( queue.empty(), true);57 queue.push(event[0]); 58 BOOST_CHECK(!queue.empty()); 59 BOOST_CHECK_EQUAL(read(&queue), 1); 78 60 79 BOOST_CHECK(recorder.pop(boost::format("sendEvent(%1%)") % id)); 80 BOOST_CHECK(recorder.isEmpty()); 61 // pop() should not leave the event in the queue 62 temp = queue.pop(); 63 BOOST_CHECK_EQUAL(temp, event[0]); 64 BOOST_CHECK_EQUAL(temp.use_count(), 2); 65 66 // Push events in order 67 for (size_t i = 0; i < count; i++) 68 queue.push(event[i]); 69 70 BOOST_CHECK_EQUAL(read(&queue), count); 71 72 // The queue should maintain order 73 for (size_t i = 0; i < count; i++) 74 { 75 temp = queue.pop(); 76 BOOST_CHECK_EQUAL(temp, event[i]); 77 BOOST_CHECK_EQUAL(temp->getId(), id[i]); 78 BOOST_CHECK_EQUAL(temp->getProperty<int>("42 * i"), (int)(42 * i)); 79 } 80 81 BOOST_CHECK(queue.empty()); 82 BOOST_CHECK_THROW(queue.pop(), Licq::RuntimeException); 81 83 } 82 84 -
branches/newapi/licq/src/plugin/plugininstanceimpl.cpp
r5952 r5975 94 94 95 95 // Create the plugin's event queue 96 mySetup.eventQueue = new EventQueue(myInformation->name, 97 Globals::getEventManager()); 96 mySetup.eventQueue = new EventQueue(myInformation->name); 98 97 99 98 // Create the plugin -
branches/newapi/licq/src/plugin/pluginmanagerimpl.cpp
r5931 r5975 68 68 // Send started event 69 69 boost::shared_ptr<Licq::Event> started = Licq::Event::create("started"); 70 instance->getEventQueue()->push Event(started);70 instance->getEventQueue()->push(started); 71 71 72 72 return id;
