Comments (6)
You're welcome to make a pull request, otherwise I will work through these changes myself.
This looks like it works, which is nice to be able to remove blocking pipe. I noticed you're using pthread_yield()
in the tests. This doesn't appear to be defined in my pthread.h
. How does it differ from sched_yield()
?
from chan.
There is no difference except for pthread_yield not being POSIX.
from chan.
I have a PR (#14) open with the proposed changes for removing blocking_pipe_t
, but I'm holding off on merging it right now since the following unit test appears to be failing sporadically:
void test_chan_select_send()
{
chan_t* chan1 = chan_init(0);
chan_t* chan2 = chan_init(1);
chan_t* chans[2] = {chan1, chan2};
void* msg[] = {"foo", "bar"};
switch(chan_select(NULL, 0, NULL, chans, 2, msg))
{
case 0:
chan_dispose(chan1);
chan_dispose(chan2);
fprintf(stderr, "Sent on wrong channel");
exit(1);
case 1:
break;
default:
chan_dispose(chan1);
chan_dispose(chan2);
fprintf(stderr, "Sent on no channels");
exit(1);
}
void* recv;
chan_recv(chan2, &recv);
if (strcmp(recv, "bar") != 0)
{
chan_dispose(chan1);
chan_dispose(chan2);
fprintf(stderr, "Messages are not equal");
exit(1);
}
chan_send(chan2, "foo");
pthread_t th;
pthread_create(&th, NULL, receiver, chan1);
sleep(1);
switch(chan_select(NULL, 0, NULL, chans, 2, msg))
{
case 0:
break;
case 1:
chan_dispose(chan1);
chan_dispose(chan2);
fprintf(stderr, "Sent on wrong channel");
exit(1);
default:
chan_dispose(chan1);
chan_dispose(chan2);
fprintf(stderr, "Sent on no channels");
exit(1);
}
switch(chan_select(NULL, 0, NULL, &chan1, 1, msg[0]))
{
case 0:
chan_dispose(chan1);
chan_dispose(chan2);
fprintf(stderr, "Sent on channel");
exit(1);
default:
break;
}
chan_dispose(chan1);
chan_dispose(chan2);
pass();
}
The failure is almost certainly due to the race condition here:
pthread_t th;
pthread_create(&th, NULL, receiver, chan1);
sleep(1);
...
We're hitting the chan_select
before the recv is executed. Issue is unrelated to the removal of the blocking pipe.
from chan.
I'm attempting to replace all instances of sleep(1)
with the following (or its writer equivalent):
void wait_for_reader(chan_t* chan)
{
for (;;)
{
pthread_mutex_lock(&chan->m_mu);
int send = chan->r_waiting > 0;
pthread_mutex_unlock(&chan->m_mu);
if (send) break;
sched_yield();
}
}
For some reason, this occasionally results in an infinite loop. It isn't entirely clear to me why this would be happening since wait_for_reader
is being called on an unbuffered channel before a call to send, so r_waiting
should eventually be incremented to 1 and the reader thread blocked.
from chan.
Try adding pthread_join(&th, NULL); in every test where you create a thread.
I sometimes have memory corruption errors due to started threads hanging around.
For example
pthread_create(&th, NULL, sender, chan);
assert_true(...);
...
chan_dispose(chan);
There is a race if chan is disposed before sender is run (memory corruption possible).
Also:
I've replaced sleep(1); with wait_for_writer(chan1); in test_chan_select_recv()
cause sometimes the whole test aborted.
The reason: In case of an error chan_dispose is called without a preceding pthread_join.
This produces a memory corruption if the created thread has not been run first.
from chan.
Yep—that fixed it, thanks!
from chan.
Related Issues (16)
- memory not freed HOT 10
- deadlock HOT 1
- deadlock2 HOT 2
- Proposol: Removing unecessary malloc/free in queue_t HOT 1
- Clibs package HOT 5
- Missing speed test HOT 8
- change implementation language to C HOT 2
- chan_recv can receive duplicate sent values
- optional size param for send/recv
- Will select block if chan_can_recv first true then false?
- Does this facilitate C - Go communication? HOT 4
- problem of threads?
- C2x feature proposal?
- Add support for blocking selects
- primitive values HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from chan.