1 #include "TestUrgency.h"
2 
3 #include "IPDLUnitTests.h"  // fail etc.
4 #if defined(OS_POSIX)
5 #  include <unistd.h>
6 #else
7 #  include <windows.h>
8 #endif
9 
10 namespace mozilla {
11 namespace _ipdltest {
12 
13 #if defined(OS_POSIX)
Sleep(int ms)14 static void Sleep(int ms) { sleep(ms / 1000); }
15 #endif
16 
17 //-----------------------------------------------------------------------------
18 // parent
19 
TestUrgencyParent()20 TestUrgencyParent::TestUrgencyParent() : inreply_(false) {
21   MOZ_COUNT_CTOR(TestUrgencyParent);
22 }
23 
~TestUrgencyParent()24 TestUrgencyParent::~TestUrgencyParent() { MOZ_COUNT_DTOR(TestUrgencyParent); }
25 
Main()26 void TestUrgencyParent::Main() {
27   if (!SendStart()) fail("sending Start");
28 }
29 
RecvTest1(uint32_t * value)30 mozilla::ipc::IPCResult TestUrgencyParent::RecvTest1(uint32_t* value) {
31   if (!SendReply1(value)) fail("sending Reply1");
32   if (*value != 99) fail("bad value");
33   return IPC_OK();
34 }
35 
RecvTest2()36 mozilla::ipc::IPCResult TestUrgencyParent::RecvTest2() {
37   uint32_t value;
38   inreply_ = true;
39   if (!SendReply2(&value)) fail("sending Reply2");
40   inreply_ = false;
41   if (value != 500) fail("bad value");
42   return IPC_OK();
43 }
44 
RecvTest3(uint32_t * value)45 mozilla::ipc::IPCResult TestUrgencyParent::RecvTest3(uint32_t* value) {
46   if (inreply_) fail("nested non-urgent on top of urgent rpc");
47   *value = 1000;
48   return IPC_OK();
49 }
50 
RecvFinalTest_Begin()51 mozilla::ipc::IPCResult TestUrgencyParent::RecvFinalTest_Begin() {
52   return IPC_OK();
53 }
54 
55 //-----------------------------------------------------------------------------
56 // child
57 
58 enum {
59   kFirstTestBegin = 1,
60   kFirstTestGotReply,
61   kSecondTestBegin,
62   kSecondTestGotReply,
63 };
64 
RecvStart()65 mozilla::ipc::IPCResult TestUrgencyChild::RecvStart() {
66   uint32_t result;
67 
68   // Send a synchronous message, expect to get an urgent message while
69   // blocked.
70   test_ = kFirstTestBegin;
71   if (!SendTest1(&result)) fail("calling SendTest1");
72   if (result != 99) fail("bad result in RecvStart");
73   if (test_ != kFirstTestGotReply) fail("never received urgent message");
74 
75   // Initiate the next test by sending an asynchronous message, then becoming
76   // blocked. This tests that the urgent message is still delivered properly,
77   // and that the parent does not try to service the sync
78   test_ = kSecondTestBegin;
79   if (!SendTest2()) fail("calling SendTest2");
80   if (!SendTest3(&result)) fail("calling SendTest3");
81   if (test_ != kSecondTestGotReply) fail("never received urgent message #2");
82   if (result != 1000) fail("wrong value from test3");
83 
84   if (!SendFinalTest_Begin()) fail("Final test should have succeeded");
85 
86   Close();
87 
88   return IPC_OK();
89 }
90 
RecvReply1(uint32_t * reply)91 mozilla::ipc::IPCResult TestUrgencyChild::RecvReply1(uint32_t* reply) {
92   if (test_ != kFirstTestBegin) fail("wrong test # in RecvReply1");
93 
94   *reply = 99;
95   test_ = kFirstTestGotReply;
96   return IPC_OK();
97 }
98 
RecvReply2(uint32_t * reply)99 mozilla::ipc::IPCResult TestUrgencyChild::RecvReply2(uint32_t* reply) {
100   if (test_ != kSecondTestBegin) fail("wrong test # in RecvReply2");
101 
102   // sleep for 5 seconds so the parent process tries to deliver more messages.
103   Sleep(5000);
104 
105   *reply = 500;
106   test_ = kSecondTestGotReply;
107   return IPC_OK();
108 }
109 
TestUrgencyChild()110 TestUrgencyChild::TestUrgencyChild() : test_(0) {
111   MOZ_COUNT_CTOR(TestUrgencyChild);
112 }
113 
~TestUrgencyChild()114 TestUrgencyChild::~TestUrgencyChild() { MOZ_COUNT_DTOR(TestUrgencyChild); }
115 
116 }  // namespace _ipdltest
117 }  // namespace mozilla
118