aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2010-01-18 17:25:08 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2010-01-18 17:25:08 +0000
commit7e02520614efa677c1d8683df69a09c9f650d105 (patch)
treef3e8a41c7c61aebfd02078850dc577d1468567b1 /net
parent2ab854a149b270e9b3c5218fc9b20d603a633a1d (diff)
Make the connection thread detached and don't refer to its struct directly, check for thread
creation errors. svn path=/trunk/externals/mrpeach/; revision=13037
Diffstat (limited to 'net')
-rw-r--r--net/udpsend~-help.pd5
-rw-r--r--net/udpsend~.c50
-rw-r--r--net/udpsend~.h2
3 files changed, 38 insertions, 19 deletions
diff --git a/net/udpsend~-help.pd b/net/udpsend~-help.pd
index f8bc684..1a0ab83 100644
--- a/net/udpsend~-help.pd
+++ b/net/udpsend~-help.pd
@@ -66,7 +66,7 @@ per sample);
#X text 70 430 dsp vector size:;
#X msg -258 200 channels \$1;
#X obj -412 185 hradio 15 1 0 4 empty empty empty 0 -8 0 10 -4034 -1
--1 2;
+-1 0;
#X obj -178 297 udpsend~ 2 512;
#X text -88 296 sends 2 dsp-channels using 512-sample blocks;
#X obj -397 541 udpreceive~ 8008 2 512;
@@ -108,6 +108,8 @@ if nothing is receiving.;
#X text -256 540 receives 2 channels on port 8008 Same blocksize as
udpsend~;
#X floatatom -412 216 5 0 0 0 - - -;
+#X obj -288 172 tgl 15 0 empty empty toggle_connection 17 7 0 10 -4034
+-1 -1 0 1;
#X connect 0 0 54 0;
#X connect 1 0 62 0;
#X connect 2 0 62 0;
@@ -159,3 +161,4 @@ udpsend~;
#X connect 73 8 74 0;
#X connect 73 9 8 0;
#X connect 82 0 64 0;
+#X connect 89 0 62 0;
diff --git a/net/udpsend~.c b/net/udpsend~.c
index 7e155c9..b376ffb 100644
--- a/net/udpsend~.c
+++ b/net/udpsend~.c
@@ -101,16 +101,17 @@ typedef struct _udpsend_tilde
int x_ninlets; /* number of inlets */
int x_channels; /* number of channels we want to stream */
int x_format; /* format of streamed audio data */
-// int x_bitrate; /* specifies bitrate for compressed formats */
int x_count; /* total number of audio frames */
t_int **x_myvec; /* vector we pass on in the DSP routine */
pthread_mutex_t x_mutex;
- pthread_cond_t x_requestcondition;
- pthread_cond_t x_answercondition;
- pthread_t x_childthread;
+ pthread_t x_childthread; /* a thread to initiate a connection to the remote port */
+ pthread_attr_t x_childthread_attr; /* child thread should have detached attribute so it can be cleaned up after it exits. */
+ int x_childthread_result; /* result from pthread_create. Zero if x_childthread represents a valid thread. */
} t_udpsend_tilde;
+#define NO_CHILDTHREAD 1 /* not zero */
+
/* function prototypes */
static int udpsend_tilde_sockerror(char *s);
static void udpsend_tilde_closesocket(int fd);
@@ -132,8 +133,8 @@ void udpsend_tilde_setup(void);
static void udpsend_tilde_notify(t_udpsend_tilde *x)
{
pthread_mutex_lock(&x->x_mutex);
- x->x_childthread = NULL;
- outlet_float(x->x_outlet, x->x_connectstate);
+ x->x_childthread_result = NO_CHILDTHREAD; /* connection thread has ended */
+ outlet_float(x->x_outlet, x->x_connectstate); /* we should be connected */
pthread_mutex_unlock(&x->x_mutex);
}
@@ -150,6 +151,7 @@ static void udpsend_tilde_disconnect(t_udpsend_tilde *x)
pthread_mutex_unlock(&x->x_mutex);
}
+/* udpsend_tilde_doconnect runs in the child thread, which terminates as soon as a connection is */
static void *udpsend_tilde_doconnect(void *zz)
{
t_udpsend_tilde *x = (t_udpsend_tilde *)zz;
@@ -171,7 +173,7 @@ static void *udpsend_tilde_doconnect(void *zz)
{
post("udpsend~: connection to %s on port %d failed", hostname->s_name,portno);
udpsend_tilde_sockerror("socket");
- x->x_childthread = NULL;
+ x->x_childthread_result = NO_CHILDTHREAD;
return (0);
}
@@ -181,7 +183,7 @@ static void *udpsend_tilde_doconnect(void *zz)
if (hp == 0)
{
post("udpsend~: bad host?");
- x->x_childthread = NULL;
+ x->x_childthread_result = NO_CHILDTHREAD;
return (0);
}
@@ -204,7 +206,7 @@ static void *udpsend_tilde_doconnect(void *zz)
{
udpsend_tilde_sockerror("connecting stream socket");
udpsend_tilde_closesocket(sockfd);
- x->x_childthread = NULL;
+ x->x_childthread_result = NO_CHILDTHREAD;
return (0);
}
@@ -213,7 +215,7 @@ static void *udpsend_tilde_doconnect(void *zz)
pthread_mutex_lock(&x->x_mutex);
x->x_fd = sockfd;
x->x_connectstate = 1;
- clock_delay(x->x_clock, 0);
+ clock_delay(x->x_clock, 0);/* udpsend_tilde_notify is called in next clock tick */
pthread_mutex_unlock(&x->x_mutex);
return (0);
}
@@ -221,7 +223,7 @@ static void *udpsend_tilde_doconnect(void *zz)
static void udpsend_tilde_connect(t_udpsend_tilde *x, t_symbol *host, t_floatarg fportno)
{
pthread_mutex_lock(&x->x_mutex);
- if (x->x_childthread != NULL)
+ if (x->x_childthread_result == 0)
{
pthread_mutex_unlock(&x->x_mutex);
post("udpsend~: already trying to connect");
@@ -246,7 +248,25 @@ static void udpsend_tilde_connect(t_udpsend_tilde *x, t_symbol *host, t_floatarg
x->x_count = 0;
/* start child thread to connect */
- pthread_create(&x->x_childthread, 0, udpsend_tilde_doconnect, x);
+ /* sender thread should start out detached so its resouces will be freed when it is done */
+ if (0!= (x->x_childthread_result = pthread_attr_init(&x->x_childthread_attr)))
+ {
+ pthread_mutex_unlock(&x->x_mutex);
+ post("udpsend~: pthread_attr_init failed: %d", x->x_childthread_result);
+ return;
+ }
+ if(0!= (x->x_childthread_result = pthread_attr_setdetachstate(&x->x_childthread_attr, PTHREAD_CREATE_DETACHED)))
+ {
+ pthread_mutex_unlock(&x->x_mutex);
+ post("udpsend~: pthread_attr_setdetachstate failed: %d", x->x_childthread_result);
+ return;
+ }
+ if (0 != (x->x_childthread_result = pthread_create(&x->x_childthread, &x->x_childthread_attr, udpsend_tilde_doconnect, x)))
+ {
+ pthread_mutex_unlock(&x->x_mutex);
+ post("udpsend~: couldn't create sender thread (%d)", x->x_childthread_result);
+ return;
+ }
pthread_mutex_unlock(&x->x_mutex);
}
@@ -553,13 +573,11 @@ static void *udpsend_tilde_new(t_floatarg inlets, t_floatarg blocksize)
}
pthread_mutex_init(&x->x_mutex, 0);
- pthread_cond_init(&x->x_requestcondition, 0);
- pthread_cond_init(&x->x_answercondition, 0);
x->x_hostname = ps_localhost;
x->x_portno = DEFAULT_PORT;
x->x_connectstate = 0;
- x->x_childthread = NULL;
+ x->x_childthread_result = NO_CHILDTHREAD;
x->x_fd = -1;
x->x_tag.format = x->x_format = SF_FLOAT;
@@ -597,8 +615,6 @@ static void udpsend_tilde_free(t_udpsend_tilde* x)
clock_free(x->x_clock);
- pthread_cond_destroy(&x->x_requestcondition);
- pthread_cond_destroy(&x->x_answercondition);
pthread_mutex_destroy(&x->x_mutex);
}
diff --git a/net/udpsend~.h b/net/udpsend~.h
index af1e07e..437cff7 100644
--- a/net/udpsend~.h
+++ b/net/udpsend~.h
@@ -34,7 +34,7 @@
/* Some enhancements have been made with the goal of keeping compatibility */
/* between the stream formats of streamout~/in~ and netsend~/receive~. */
-#define VERSION "0.2"
+#define VERSION "0.3"
#define DEFAULT_AUDIO_CHANNELS 32 /* nax. number of audio channels we support */
#define DEFAULT_AUDIO_BUFFER_SIZE 2048 /*1024*/ /* number of samples in one audio block */