Skip to content

Commit 8ed921e

Browse files
committed
Hold ZMQSocket in a ScopedPointer rather than extending unique_ptr
1 parent e31f6f5 commit 8ed921e

2 files changed

Lines changed: 56 additions & 42 deletions

File tree

Source/Plugins/EventBroadcaster/EventBroadcaster.cpp

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ void* EventBroadcaster::ZMQContext::createZMQSocket()
4141
#endif
4242
}
4343

44-
EventBroadcaster::ZMQSocketPtr::ZMQSocketPtr()
45-
: std::unique_ptr<void, decltype(&closeZMQSocket)>(nullptr, &closeZMQSocket)
44+
EventBroadcaster::ZMQSocket::ZMQSocket()
45+
: socket(nullptr)
4646
{
4747
ScopedLock lock(sharedContextLock);
4848
if (sharedContext == nullptr)
@@ -57,47 +57,53 @@ EventBroadcaster::ZMQSocketPtr::ZMQSocketPtr()
5757
}
5858

5959
#ifdef ZEROMQ
60-
reset(context->createZMQSocket());
60+
socket = context->createZMQSocket();
6161
#endif
6262
}
6363

64-
EventBroadcaster::ZMQSocketPtr::~ZMQSocketPtr()
64+
EventBroadcaster::ZMQSocket::~ZMQSocket()
6565
{
66-
// close the socket before the context might get destroyed.
67-
reset(nullptr);
66+
#ifdef ZEROMQ
67+
zmq_close(socket);
68+
#endif
69+
}
70+
71+
bool EventBroadcaster::ZMQSocket::isValid() const
72+
{
73+
return socket != nullptr;
6874
}
6975

70-
int EventBroadcaster::unbindZMQSocket()
76+
int EventBroadcaster::ZMQSocket::send(const void* buf, size_t len, int flags)
7177
{
7278
#ifdef ZEROMQ
73-
void* socket = zmqSocket.get();
74-
if (socket != nullptr && listeningPort != 0)
75-
{
76-
return zmq_unbind(socket, getEndpoint(listeningPort).toRawUTF8());
77-
}
79+
return zmq_send(socket, buf, len, flags);
7880
#endif
7981
return 0;
8082
}
8183

82-
int EventBroadcaster::rebindZMQSocket()
84+
int EventBroadcaster::ZMQSocket::bind(int port)
8385
{
8486
#ifdef ZEROMQ
85-
void* socket = zmqSocket.get();
86-
if (socket != nullptr && listeningPort != 0)
87+
if (isValid() && port != 0)
8788
{
88-
return zmq_bind(socket, getEndpoint(listeningPort).toRawUTF8());
89+
return zmq_bind(socket, getEndpoint(port).toRawUTF8());
8990
}
9091
#endif
9192
return 0;
9293
}
9394

94-
void EventBroadcaster::closeZMQSocket(void* socket)
95+
int EventBroadcaster::ZMQSocket::unbind(int port)
9596
{
9697
#ifdef ZEROMQ
97-
zmq_close(socket);
98+
if (isValid() && port != 0)
99+
{
100+
return zmq_unbind(socket, getEndpoint(port).toRawUTF8());
101+
}
98102
#endif
103+
return 0;
99104
}
100105

106+
101107
String EventBroadcaster::getEndpoint(int port)
102108
{
103109
return String("tcp://*:") + String(port);
@@ -147,34 +153,38 @@ int EventBroadcaster::setListeningPort(int port, bool forceRestart)
147153
{
148154
#ifdef ZEROMQ
149155
// unbind current socket (if any) to free up port
150-
unbindZMQSocket();
151-
ZMQSocketPtr newSocket;
156+
if (zmqSocket != nullptr)
157+
{
158+
zmqSocket->unbind(listeningPort);
159+
}
160+
161+
ScopedPointer<ZMQSocket> newSocket = new ZMQSocket();
152162
auto editor = static_cast<EventBroadcasterEditor*>(getEditor());
153163
int status = 0;
154164

155-
if (!newSocket.get())
165+
if (!newSocket->isValid())
156166
{
157167
status = zmq_errno();
158168
std::cout << "Failed to create socket: " << zmq_strerror(status) << std::endl;
159169
}
160170
else
161171
{
162-
if (0 != zmq_bind(newSocket.get(), getEndpoint(port).toRawUTF8()))
172+
if (0 != newSocket->bind(port))
163173
{
164174
status = zmq_errno();
165-
std::cout << "Failed to open socket: " << zmq_strerror(status) << std::endl;
175+
std::cout << "Failed to create socket: " << zmq_strerror(status) << std::endl;
166176
}
167177
else
168178
{
169179
// success
170-
zmqSocket.swap(newSocket);
180+
zmqSocket = newSocket;
171181
reportActualListeningPort(port);
172182
return status;
173183
}
174184
}
175185

176186
// failure, try to rebind current socket to previous port
177-
if (0 == rebindZMQSocket())
187+
if (zmqSocket != nullptr && 0 == zmqSocket->bind(listeningPort))
178188
{
179189
reportActualListeningPort(listeningPort);
180190
}
@@ -183,7 +193,6 @@ int EventBroadcaster::setListeningPort(int port, bool forceRestart)
183193
reportActualListeningPort(0);
184194
}
185195
return status;
186-
187196
#else
188197
reportActualListeningPort(port);
189198
return 0;
@@ -202,13 +211,17 @@ void EventBroadcaster::process(AudioSampleBuffer& continuousBuffer)
202211
//IMPORTANT: The structure of the event buffers has changed drastically, so we need to find a better way of doing this
203212
void EventBroadcaster::sendEvent(const MidiMessage& event, float eventSampleRate) const
204213
{
214+
#ifdef ZEROMQ
205215
double timestampSeconds = double(Event::getTimestamp(event)) / eventSampleRate;
206216
uint16 type = Event::getBaseType(event);
207217

208-
#ifdef ZEROMQ
209-
if (-1 == zmq_send(zmqSocket.get(), &type, sizeof(type), ZMQ_SNDMORE) ||
210-
-1 == zmq_send(zmqSocket.get(), &timestampSeconds, sizeof(timestampSeconds), ZMQ_SNDMORE) ||
211-
-1 == zmq_send(zmqSocket.get(), event.getRawData(), event.getRawDataSize(), 0))
218+
if (!zmqSocket)
219+
{
220+
std::cout << "Failed to send message: no socket" << std::endl;
221+
}
222+
else if (-1 == zmqSocket->send(&type, sizeof(type), ZMQ_SNDMORE) ||
223+
-1 == zmqSocket->send(&timestampSeconds, sizeof(timestampSeconds), ZMQ_SNDMORE) ||
224+
-1 == zmqSocket->send(event.getRawData(), event.getRawDataSize(), 0))
212225
{
213226
std::cout << "Failed to send message: " << zmq_strerror(zmq_errno()) << std::endl;
214227
}

Source/Plugins/EventBroadcaster/EventBroadcaster.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
#endif
2323
#endif
2424

25-
#include <memory>
26-
2725
class EventBroadcaster : public GenericProcessor
2826
{
2927
public:
@@ -33,7 +31,7 @@ class EventBroadcaster : public GenericProcessor
3331

3432
int getListeningPort() const;
3533
// returns 0 on success, else the errno value for the error that occurred.
36-
int setListeningPort (int port, bool forceRestart = false);
34+
int setListeningPort(int port, bool forceRestart = false);
3735

3836
void process (AudioSampleBuffer& continuousBuffer) override;
3937
void handleEvent (const EventChannel* channelInfo, const MidiMessage& event, int samplePosition = 0) override;
@@ -54,19 +52,21 @@ class EventBroadcaster : public GenericProcessor
5452
void* context;
5553
};
5654

57-
static void closeZMQSocket(void* socket);
58-
59-
class ZMQSocketPtr : public std::unique_ptr<void, decltype(&closeZMQSocket)>
55+
class ZMQSocket
6056
{
6157
public:
62-
ZMQSocketPtr();
63-
~ZMQSocketPtr();
58+
ZMQSocket();
59+
~ZMQSocket();
60+
61+
bool isValid() const;
62+
63+
int send(const void* buf, size_t len, int flags);
64+
int bind(int port);
65+
int unbind(int port);
6466
private:
67+
void* socket;
6568
ReferenceCountedObjectPtr<ZMQContext> context;
6669
};
67-
68-
int unbindZMQSocket();
69-
int rebindZMQSocket();
7070

7171
void sendEvent(const MidiMessage& event, float eventSampleRate) const;
7272
static String getEndpoint(int port);
@@ -78,7 +78,8 @@ class EventBroadcaster : public GenericProcessor
7878
// destroyed (see: https://github.com/zeromq/libzmq/issues/1708)
7979
static ZMQContext* sharedContext;
8080
static CriticalSection sharedContextLock;
81-
ZMQSocketPtr zmqSocket;
81+
82+
ScopedPointer<ZMQSocket> zmqSocket;
8283
int listeningPort;
8384
};
8485

0 commit comments

Comments
 (0)