Skip to content

Commit 1f62174

Browse files
authored
OfxOscReceiver: from detach() to join() (#7949)
#changelog #addon
1 parent e587c1d commit 1f62174

5 files changed

Lines changed: 177 additions & 8 deletions

File tree

addons/ofxOsc/src/ofxOscReceiver.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ ofxOscReceiver & ofxOscReceiver::copy(const ofxOscReceiver & other) {
3030
//--------------------------------------------------------------
3131
bool ofxOscReceiver::setup(std::string host, int port) {
3232
if (listenSocket) { // already running
33+
ofLogVerbose("ofxOscReceiver::setup()") << "socket already listening";
3334
stop();
3435
}
3536
settings.port = port;
@@ -78,7 +79,7 @@ bool ofxOscReceiver::start() {
7879
if (!what.empty() && what.back() == '\n') {
7980
what = what.substr(0, what.size() - 1);
8081
}
81-
ofLogError("ofxOscReceiver") << "couldn't create receiver on port "
82+
ofLogError("ofxOscReceiver::start()") << "couldn't create receiver on port "
8283
<< settings.port << ": " << what;
8384
if (socket != nullptr) {
8485
delete socket;
@@ -88,25 +89,38 @@ bool ofxOscReceiver::start() {
8889
}
8990

9091
listenThread = std::thread([this] {
91-
while (listenSocket) {
92-
try {
93-
listenSocket->Run();
94-
} catch (std::exception & e) {
95-
ofLogWarning("ofxOscReceiver") << e.what();
96-
}
92+
try {
93+
listenSocket->Run();
94+
} catch (std::exception & e) {
95+
ofLogWarning("ofxOscReceiver::listenSocket->Run()") << e.what();
9796
}
9897
});
9998

10099
// detach thread so we don't have to wait on it before creating a new socket
101100
// or on destruction, the custom deleter for the socket unique_ptr already
102101
// does the right thing
102+
103+
#ifndef OSC_NO_DETACH
103104
listenThread.detach();
104-
105+
#endif
105106
return true;
106107
}
107108

108109
//--------------------------------------------------------------
109110
void ofxOscReceiver::stop() {
111+
#ifdef OSC_NO_DETACH
112+
if (listenSocket) {
113+
listenSocket->AsynchronousBreak();
114+
} else {
115+
ofLogNotice("socket already torn down ");
116+
}
117+
118+
if (!listenThread.joinable()) {
119+
ofLogNotice("not joinable");
120+
} else {
121+
listenThread.join();
122+
}
123+
#endif
110124
listenSocket.reset();
111125
}
112126

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ofxOsc
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "ofMain.h"
2+
#include "ofApp.h"
3+
4+
//========================================================================
5+
int main( ){
6+
7+
//Use ofGLFWWindowSettings for more options like multi-monitor fullscreen
8+
ofGLWindowSettings settings;
9+
settings.setSize(1024, 768);
10+
settings.windowMode = OF_WINDOW; //can also be OF_FULLSCREEN
11+
12+
auto window = ofCreateWindow(settings);
13+
14+
ofRunApp(window, std::make_shared<ofApp>());
15+
ofRunMainLoop();
16+
17+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "ofApp.h"
2+
3+
#define USE_EXPLICIT_FUNCTION 1
4+
5+
#define INSTANTLY_OUT_OF_SCOPE 1
6+
7+
void ofApp::setup(){
8+
for (size_t i = 0; i < testers_.size(); i++) {
9+
testers_[i] = std::make_shared<Tester>();
10+
}
11+
ofSetVerticalSync(false);
12+
13+
#ifdef INSTANTLY_OUT_OF_SCOPE
14+
ofLogNotice("will hang");
15+
ofxOscReceiver r;
16+
#endif
17+
ofLogNotice("ready to roll");
18+
19+
}
20+
21+
void ofApp::update(){
22+
23+
if (mode_ == STOP) {
24+
if (ofGetFrameNum()%6==0) {
25+
for (const auto & tester: testers_) {
26+
tester->receiver_->stop();
27+
}
28+
} if (ofGetFrameNum()%6==3) {
29+
for (const auto & tester: testers_) {
30+
tester->receiver_->start();
31+
}
32+
}
33+
} else if (mode_ == DYNA) {
34+
if (ofGetFrameNum()%3==0) {
35+
for (const auto & tester: testers_) {
36+
tester->receiver_ = std::make_shared<ofxOscReceiver>(port_);
37+
if (tester->receiver_->isListening()) {
38+
tester->sender_ = std::make_shared<ofxOscSender>("127.0.0.1", port_);
39+
receivers_++;
40+
}
41+
if (port_++ > high_port_) port_ = low_port_;
42+
}
43+
}
44+
}
45+
46+
for (const auto & tester: testers_) {
47+
for (size_t i=0; i<10; i++) {
48+
#if defined(USE_EXPLICIT_FUNCTION)
49+
ofxOscMessage m;
50+
m.setAddress("/test");
51+
m.addIntArg(std::int32_t(i));
52+
m.addIntArg(port_);
53+
m.addIntArg(i);
54+
tester->sender_->sendMessage(m);
55+
#else
56+
ofxOscMessage m{"/test"};
57+
m.add(i);
58+
tester->sender_->sendMessage(m.add(port_).add(i));
59+
#endif
60+
msgs_out_++;
61+
}
62+
}
63+
64+
for (const auto & tester: testers_) {
65+
while (auto m = tester->receiver_->getMessage()) {
66+
msgs_++;
67+
}
68+
}
69+
}
70+
71+
void ofApp::draw() {
72+
for (int i = 0; i < 1000; i++) {
73+
ofSetColor(ofRandom(0,255), ofRandom(0, 255), ofRandom(0, 255));
74+
ofDrawRectangle(i *15, 10, 10, 50);
75+
}
76+
77+
ofSetColor(ofColor::white);
78+
ofDrawBitmapString("receivers destroyed/created: " + ofToString(receivers_), 10, 80);
79+
ofDrawBitmapString("sent: " + ofToString(msgs_out_), 10, 100);
80+
ofDrawBitmapString("received: " + ofToString(msgs_), 10, 120);
81+
auto miss = msgs_out_-msgs_;
82+
ofDrawBitmapString("= lost: " + ofToString(miss) + " (" + ofToString((float(miss)/(msgs_out_))*100.0f, 2)+"%)", 10, 140);
83+
84+
ofDrawBitmapString("mode 1: dynamic reallocation every 3 frames (<5% loss)", 10, 200);
85+
ofDrawBitmapString("mode 2: open/close every 3 frames (normal to have 50% loss)", 10, 220);
86+
ofDrawBitmapString("mode 3: stable (should have 0% loss)", 10, 240);
87+
ofDrawBitmapString("current mode: "+ofToString(mode_+1), 10, 260);
88+
89+
ofDrawBitmapString("FPS (unsync'ed to stress things): " + ofToString(ofGetFrameRate(), 2), 10, ofGetHeight()-30);
90+
}
91+
92+
void ofApp::keyPressed(int key){
93+
if (key=='1' ) mode_ = DYNA;
94+
if (key=='2' ) mode_ = STOP;
95+
if (key=='3' ) mode_ = STABLE;
96+
msgs_ = 0;
97+
msgs_out_ = 0;
98+
}
99+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include "ofMain.h"
4+
#include "ofxOsc.h"
5+
6+
struct Tester {
7+
std::shared_ptr<ofxOscSender> sender_;
8+
std::shared_ptr<ofxOscReceiver> receiver_;
9+
};
10+
11+
class ofApp : public ofBaseApp{
12+
13+
enum Mode {
14+
DYNA,
15+
STOP,
16+
STABLE
17+
};
18+
19+
Mode mode_ { DYNA };
20+
long msgs_ { 0 };
21+
long msgs_out_ { 0 };
22+
long receivers_ { 0 };
23+
24+
bool dyna_ { true } ;
25+
const size_t low_port_ { 2000 };
26+
const size_t high_port_ { 65000 };
27+
size_t port_ { low_port_ };
28+
29+
std::array<std::shared_ptr<Tester>, 10> testers_;
30+
31+
32+
public:
33+
void setup() override;
34+
void update() override;
35+
void draw() override;
36+
void keyPressed(int key) override;
37+
38+
};

0 commit comments

Comments
 (0)