OpenShot Library | libopenshot-audio  0.2.0
juce_NamedPipe.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
27 
29 {
30  close();
31 }
32 
33 bool NamedPipe::openExisting (const String& pipeName)
34 {
35  close();
36 
37  ScopedWriteLock sl (lock);
38  currentPipeName = pipeName;
39  return openInternal (pipeName, false, false);
40 }
41 
42 bool NamedPipe::isOpen() const
43 {
44  return pimpl != nullptr;
45 }
46 
47 bool NamedPipe::createNewPipe (const String& pipeName, bool mustNotExist)
48 {
49  close();
50 
51  ScopedWriteLock sl (lock);
52  currentPipeName = pipeName;
53  return openInternal (pipeName, true, mustNotExist);
54 }
55 
57 {
58  return currentPipeName;
59 }
60 
61 // other methods for this class are implemented in the platform-specific files
62 
63 //==============================================================================
64 
65 #if JUCE_UNIT_TESTS
66 
67 class NamedPipeTests : public UnitTest
68 {
69 public:
70  //==============================================================================
71  NamedPipeTests()
72  : UnitTest ("NamedPipe", "Networking")
73  {}
74 
75  void runTest() override
76  {
77  const String pipeName ("TestPipe");
78 
79  beginTest ("Pre test cleanup");
80  {
81  NamedPipe pipe;
82  expect (pipe.createNewPipe (pipeName, false));
83  }
84 
85  beginTest ("Create pipe");
86  {
87  NamedPipe pipe;
88  expect (! pipe.isOpen());
89 
90  expect (pipe.createNewPipe (pipeName, true));
91  expect (pipe.isOpen());
92 
93  expect (pipe.createNewPipe (pipeName, false));
94  expect (pipe.isOpen());
95 
96  NamedPipe otherPipe;
97  expect (! otherPipe.createNewPipe (pipeName, true));
98  expect (! otherPipe.isOpen());
99  }
100 
101  beginTest ("Existing pipe");
102  {
103  NamedPipe pipe;
104 
105  expect (! pipe.openExisting (pipeName));
106  expect (! pipe.isOpen());
107 
108  expect (pipe.createNewPipe (pipeName, true));
109 
110  NamedPipe otherPipe;
111  expect (otherPipe.openExisting (pipeName));
112  expect (otherPipe.isOpen());
113  }
114 
115  int sendData = 4684682;
116 
117  beginTest ("Receive message created pipe");
118  {
119  NamedPipe pipe;
120  expect (pipe.createNewPipe (pipeName, true));
121 
122  WaitableEvent senderFinished;
123  SenderThread sender (pipeName, false, senderFinished, sendData);
124 
125  sender.startThread();
126 
127  int recvData = -1;
128  auto bytesRead = pipe.read (&recvData, sizeof (recvData), 2000);
129 
130  expect (senderFinished.wait (4000));
131 
132  expectEquals (bytesRead, (int) sizeof (recvData));
133  expectEquals (sender.result, (int) sizeof (sendData));
134  expectEquals (recvData, sendData);
135  }
136 
137  beginTest ("Receive message existing pipe");
138  {
139  WaitableEvent senderFinished;
140  SenderThread sender (pipeName, true, senderFinished, sendData);
141 
142  NamedPipe pipe;
143  expect (pipe.openExisting (pipeName));
144 
145  sender.startThread();
146 
147  int recvData = -1;
148  auto bytesRead = pipe.read (&recvData, sizeof (recvData), 2000);
149 
150  expect (senderFinished.wait (4000));
151 
152  expectEquals (bytesRead, (int) sizeof (recvData));
153  expectEquals (sender.result, (int) sizeof (sendData));
154  expectEquals (recvData, sendData);
155  }
156 
157  beginTest ("Send message created pipe");
158  {
159  NamedPipe pipe;
160  expect (pipe.createNewPipe (pipeName, true));
161 
162  WaitableEvent receiverFinished;
163  ReceiverThread receiver (pipeName, false, receiverFinished);
164 
165  receiver.startThread();
166 
167  auto bytesWritten = pipe.write (&sendData, sizeof (sendData), 2000);
168 
169  expect (receiverFinished.wait (4000));
170 
171  expectEquals (bytesWritten, (int) sizeof (sendData));
172  expectEquals (receiver.result, (int) sizeof (receiver.recvData));
173  expectEquals (receiver.recvData, sendData);
174  }
175 
176  beginTest ("Send message existing pipe");
177  {
178  WaitableEvent receiverFinished;
179  ReceiverThread receiver (pipeName, true, receiverFinished);
180 
181  NamedPipe pipe;
182  expect (pipe.openExisting (pipeName));
183 
184  receiver.startThread();
185 
186  auto bytesWritten = pipe.write (&sendData, sizeof (sendData), 2000);
187 
188  expect (receiverFinished.wait (4000));
189 
190  expectEquals (bytesWritten, (int) sizeof (sendData));
191  expectEquals (receiver.result, (int) sizeof (receiver.recvData));
192  expectEquals (receiver.recvData, sendData);
193  }
194  }
195 
196 private:
197  //==============================================================================
198  struct NamedPipeThread : public Thread
199  {
200  NamedPipeThread (const String& threadName, const String& pName,
201  bool shouldCreatePipe, WaitableEvent& completed)
202  : Thread (threadName), pipeName (pName), workCompleted (completed)
203  {
204  if (shouldCreatePipe)
205  pipe.createNewPipe (pipeName);
206  else
207  pipe.openExisting (pipeName);
208  }
209 
210  NamedPipe pipe;
211  const String& pipeName;
212  WaitableEvent& workCompleted;
213 
214  int result = -2;
215  };
216 
217  //==============================================================================
218  struct SenderThread : public NamedPipeThread
219  {
220  SenderThread (const String& pName, bool shouldCreatePipe,
221  WaitableEvent& completed, int sData)
222  : NamedPipeThread ("NamePipeSender", pName, shouldCreatePipe, completed),
223  sendData (sData)
224  {}
225 
226  void run() override
227  {
228  result = pipe.write (&sendData, sizeof (sendData), 2000);
229  workCompleted.signal();
230  }
231 
232  const int sendData;
233  };
234 
235  //==============================================================================
236  struct ReceiverThread : public NamedPipeThread
237  {
238  ReceiverThread (const String& pName, bool shouldCreatePipe,
239  WaitableEvent& completed)
240  : NamedPipeThread ("NamePipeSender", pName, shouldCreatePipe, completed)
241  {}
242 
243  void run() override
244  {
245  result = pipe.read (&recvData, sizeof (recvData), 2000);
246  workCompleted.signal();
247  }
248 
249  int recvData = -2;
250  };
251 };
252 
253 static NamedPipeTests namedPipeTests;
254 
255 #endif
256 
257 } // namespace juce
juce::NamedPipe::~NamedPipe
~NamedPipe()
Destructor.
Definition: juce_NamedPipe.cpp:28
juce::NamedPipe::openExisting
bool openExisting(const String &pipeName)
Tries to open a pipe that already exists.
Definition: juce_NamedPipe.cpp:33
juce::NamedPipe::close
void close()
Closes the pipe, if it's open.
juce::ScopedWriteLock
Automatically locks and unlocks a ReadWriteLock object.
Definition: juce_ScopedWriteLock.h:55
juce::NamedPipe::createNewPipe
bool createNewPipe(const String &pipeName, bool mustNotExist=false)
Tries to create a new pipe.
Definition: juce_NamedPipe.cpp:47
juce::NamedPipe::isOpen
bool isOpen() const
True if the pipe is currently open.
Definition: juce_NamedPipe.cpp:42
juce::NamedPipe::NamedPipe
NamedPipe()
Creates a NamedPipe.
Definition: juce_NamedPipe.cpp:26
juce::UnitTest
This is a base class for classes that perform a unit test.
Definition: juce_UnitTest.h:73
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::NamedPipe::getName
String getName() const
Returns the last name that was used to try to open this pipe.
Definition: juce_NamedPipe.cpp:56