summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/Neptune/Source/Tests/Queue1/QueueTest1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libUPnP/Neptune/Source/Tests/Queue1/QueueTest1.cpp')
-rw-r--r--lib/libUPnP/Neptune/Source/Tests/Queue1/QueueTest1.cpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/lib/libUPnP/Neptune/Source/Tests/Queue1/QueueTest1.cpp b/lib/libUPnP/Neptune/Source/Tests/Queue1/QueueTest1.cpp
new file mode 100644
index 0000000..6afa535
--- /dev/null
+++ b/lib/libUPnP/Neptune/Source/Tests/Queue1/QueueTest1.cpp
@@ -0,0 +1,302 @@
+/*****************************************************************
+|
+| Queue Test Program 1
+|
+| (c) 2008 Gilles Boccon-Gibod
+| Author: Gilles Boccon-Gibod (bok@bok.net)
+|
+ ****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "Neptune.h"
+
+#if defined(WIN32) && defined(_DEBUG)
+#include <crtdbg.h>
+#endif
+
+#define CHECK(x) { \
+ if (!(x)) { \
+ printf("TEST FAILED line %d\n", __LINE__); \
+ NPT_ASSERT(0); \
+ } \
+}
+
+/*----------------------------------------------------------------------
+| Item
++---------------------------------------------------------------------*/
+class Item
+{
+public:
+ typedef enum {
+ MSG_INCREMENT_COUNTER,
+ MSG_CHANGE_TIMEOUT,
+ MSG_TERMINATE
+ } Message;
+
+ Item(Message msg) : m_Message(msg) {}
+
+ Message m_Message;
+};
+
+/*----------------------------------------------------------------------
+| WriterThread
++---------------------------------------------------------------------*/
+class WriterThread : public NPT_Thread
+{
+public:
+ WriterThread(NPT_Queue<Item>& queue, const char* name) :
+ m_Queue(queue), m_Name(name), m_Counter(0) {}
+
+ void Run() {
+ NPT_Debug("WRITER %s starting ++++++++++++++++++++++++\n", (const char*)m_Name);
+
+ for (int i=0; i<1000; i++) {
+ if (i%5 == 0) {
+ NPT_Debug("WRITER %s post: change timeout\n", (const char*)m_Name);
+ m_Queue.Push(new Item(Item::MSG_CHANGE_TIMEOUT));
+ }
+ m_Queue.Push(new Item(Item::MSG_INCREMENT_COUNTER));
+ if (i%3 == 0) {
+ NPT_Debug("WRITER %s sleeping\n", (const char*)m_Name);
+ NPT_System::Sleep(NPT_TimeInterval(0.01f));
+ }
+ }
+
+ NPT_Debug("WRITER %s terminating ----------------------\n", (const char*)m_Name);
+ }
+
+ NPT_Queue<Item>& m_Queue;
+ NPT_String m_Name;
+ unsigned int m_Counter;
+};
+
+/*----------------------------------------------------------------------
+| ReaderThread
++---------------------------------------------------------------------*/
+class ReaderThread : public NPT_Thread
+{
+public:
+ ReaderThread(NPT_Queue<Item>& queue, const char* name, NPT_TimeInterval sleep_time) :
+ m_Queue(queue), m_Name(name), m_Counter(0), m_NbTimeouts(0), m_SleepTime(sleep_time) {}
+
+ void Run() {
+ NPT_Debug("READER %s starting =====================\n", (const char*)m_Name);
+ NPT_Timeout timeout = NPT_TIMEOUT_INFINITE;
+ for (;;) {
+ if (m_SleepTime.ToNanos() != 0) {
+ NPT_Debug("READER %s sleeping...\n", (const char*)m_Name);
+ NPT_System::Sleep(m_SleepTime);
+ NPT_Debug("READER %s woke up!\n", (const char*)m_Name);
+ }
+
+ Item* item = NULL;
+ NPT_Result result = m_Queue.Pop(item, timeout);
+ if (NPT_SUCCEEDED(result)) {
+ CHECK(item != NULL);
+ Item::Message msg = item->m_Message;
+ delete item;
+ switch (msg) {
+ case Item::MSG_INCREMENT_COUNTER:
+ ++m_Counter;
+ NPT_Debug("READER %s new counter=%d\n", (const char*)m_Name, m_Counter);
+ break;
+
+ case Item::MSG_CHANGE_TIMEOUT:
+ if (timeout == 0) {
+ timeout = 15;
+ } else if (timeout == 15) {
+ timeout = NPT_TIMEOUT_INFINITE;
+ } else {
+ timeout = 0;
+ }
+ NPT_Debug("READER %s new timeout=%d\n", (const char*)m_Name, timeout);
+ break;
+
+ case Item::MSG_TERMINATE:
+ NPT_Debug("READER %s terminating #######################\n", (const char*)m_Name);
+ return;
+ }
+ } else {
+ NPT_Debug("READER %s pop returned %d\n", (const char*)m_Name, result);
+ if (timeout == 0) {
+ CHECK(result == NPT_ERROR_LIST_EMPTY);
+ NPT_System::Sleep(0.01f);
+ } else if (timeout != NPT_TIMEOUT_INFINITE) {
+ CHECK(result == NPT_ERROR_TIMEOUT);
+ ++m_NbTimeouts;
+ } else {
+ NPT_ASSERT(0);
+ }
+ }
+ }
+ }
+
+ NPT_Queue<Item>& m_Queue;
+ NPT_String m_Name;
+ unsigned int m_Counter;
+ unsigned int m_NbTimeouts;
+ NPT_TimeInterval m_SleepTime;
+};
+
+/*----------------------------------------------------------------------
+| Test1
++---------------------------------------------------------------------*/
+static void
+Test1()
+{
+ // create a queue
+ NPT_Queue<Item> queue;
+
+ // create 2 writers
+ NPT_Debug("creating writer 1\n");
+ WriterThread writer1(queue, "1"); writer1.Start();
+ NPT_System::Sleep(NPT_TimeInterval(0.3f));
+
+ NPT_Debug("creating writer 2\n");
+ WriterThread writer2(queue, "2"); writer2.Start();
+ NPT_System::Sleep(NPT_TimeInterval(0.3f));
+
+ // create 4 readers
+ NPT_Debug("creating reader 1\n");
+ ReaderThread reader1(queue, "1", NPT_TimeInterval(0.0f)); reader1.Start();
+ NPT_System::Sleep(NPT_TimeInterval(0.3f));
+
+ NPT_Debug("creating reader 2\n");
+ ReaderThread reader2(queue, "2", NPT_TimeInterval(0.0f)); reader2.Start();
+ NPT_System::Sleep(NPT_TimeInterval(0.3f));
+
+ NPT_Debug("creating reader 3\n");
+ ReaderThread reader3(queue, "3", NPT_TimeInterval(0.0f)); reader3.Start();
+ NPT_System::Sleep(NPT_TimeInterval(0.3f));
+
+ NPT_Debug("creating reader 4\n");
+ ReaderThread reader4(queue, "4", NPT_TimeInterval(0.0f)); reader4.Start();
+ NPT_System::Sleep(NPT_TimeInterval(0.3f));
+
+
+ // wait for the writers
+ NPT_Result result;
+ NPT_Debug("Waiting for Writer 1 *********************\n");
+ result = writer1.Wait();
+ NPT_Debug("Writer 1 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+ NPT_Debug("Waiting for Writer 2 *********************\n");
+ result = writer2.Wait();
+ NPT_Debug("Writer 1 done *********************\n");
+
+ // post 4 termination messages
+ queue.Push(new Item(Item::MSG_TERMINATE));
+ queue.Push(new Item(Item::MSG_TERMINATE));
+ queue.Push(new Item(Item::MSG_TERMINATE));
+ queue.Push(new Item(Item::MSG_TERMINATE));
+
+ // wait for the readers
+ CHECK(result == NPT_SUCCESS);
+ NPT_Debug("Waiting for Reader 1 *********************\n");
+ result = reader1.Wait();
+ NPT_Debug("Reader 1 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+ NPT_Debug("Waiting for Reader 2 *********************\n");
+ result = reader2.Wait();
+ NPT_Debug("Reader 2 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+ NPT_Debug("Waiting for Reader 3 *********************\n");
+ result = reader3.Wait();
+ NPT_Debug("Reader 3 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+ NPT_Debug("Waiting for Reader 4 *********************\n");
+ result = reader4.Wait();
+ NPT_Debug("Reader 4 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+
+ // check counters
+ unsigned int total = reader1.m_Counter+reader2.m_Counter+reader3.m_Counter+reader4.m_Counter;
+ CHECK(total == 2*1000);
+}
+
+/*----------------------------------------------------------------------
+| Test2
++---------------------------------------------------------------------*/
+static void
+Test2()
+{
+ // create a queue
+ NPT_Queue<Item> queue;
+
+ // create 2 readers
+ NPT_Debug("creating reader 1\n");
+ ReaderThread reader1(queue, "1", NPT_TimeInterval(0.05f)); reader1.Start();
+
+ NPT_Debug("creating reader 2\n");
+ ReaderThread reader2(queue, "2", NPT_TimeInterval(0.065f)); reader2.Start();
+
+ for (int i=0; i<30; i++) {
+ queue.Push(new Item(Item::MSG_INCREMENT_COUNTER));
+ }
+ queue.Push(new Item(Item::MSG_TERMINATE));
+ for (int i=0; i<30; i++) {
+ queue.Push(new Item(Item::MSG_INCREMENT_COUNTER));
+ }
+ queue.Push(new Item(Item::MSG_TERMINATE));
+
+ NPT_Result result;
+ NPT_Debug("Waiting for Reader 1 *********************\n");
+ result = reader1.Wait();
+ NPT_Debug("Reader 1 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+ NPT_Debug("Waiting for Reader 1 *********************\n");
+ result = reader2.Wait();
+ NPT_Debug("Reader 2 done *********************\n");
+ CHECK(result == NPT_SUCCESS);
+
+ // check counters
+ unsigned int total = reader1.m_Counter+reader2.m_Counter;
+ CHECK(total == 60);
+}
+
+#if defined(WIN32) && defined(_DEBUG)
+static int AllocHook( int allocType, void *userData, size_t size, int blockType,
+ long requestNumber, const unsigned char *filename, int lineNumber)
+{
+ (void)allocType;
+ (void)userData;
+ (void)size;
+ (void)blockType;
+ (void)requestNumber;
+ (void)lineNumber;
+ (void)filename;
+ return 1;
+}
+#endif
+
+/*----------------------------------------------------------------------
+| main
++---------------------------------------------------------------------*/
+int
+main(int argc, char** argv)
+{
+ NPT_COMPILER_UNUSED(argc);
+ NPT_COMPILER_UNUSED(argv);
+
+#if defined(WIN32) && defined(_DEBUG)
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |
+ _CRTDBG_CHECK_ALWAYS_DF |
+ _CRTDBG_LEAK_CHECK_DF);
+ _CrtSetAllocHook(AllocHook);
+#endif
+
+ Test1();
+ Test2();
+
+ NPT_Debug("- program done -\n");
+
+ return 0;
+}
+
+
+
+
+
+