Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

data-race when publisher catches up with the subscriber #8

Closed
filipdulic opened this issue Dec 26, 2018 · 1 comment
Closed

data-race when publisher catches up with the subscriber #8

filipdulic opened this issue Dec 26, 2018 · 1 comment
Labels
bug Something isn't working

Comments

@filipdulic
Copy link
Owner

filipdulic commented Dec 26, 2018

Publisher operations during broadcast

  1. buffer[wi % size] = item;
  2. wi++;

Subscriber operations during try_recv

  1. if ri == wi => empty
  2. item = buffer[ri % size];
  3. loop
    3.a. if wi > ri + size => ri = wi - size;
    3.b. else => ri++, return item

Test Case

wi = 10, ri = 0, size = 10, item = y, buffer[0] = x.

  1. pub.1. buffer[10 % 10] = item; <==> buffer[0] = y;
  2. sub.1. if 0 == 10 ==> not empty
  3. sub.2. item = buffer[0] <==> item = y;
  4. sub.3.a. if 10 > 0 + 10 => sub.3.b
  5. sub.3.b ri++ => 1, return y.

y is returned even though x should have been, or sub should have moved to next.

@filipdulic
Copy link
Owner Author

filipdulic commented Dec 26, 2018

Possible fix.

Change the check in sub 3.a to if wi >= ri + size => ri = wi - size + 1;

From

if self.wi() > self.ri() + self.size { self.ri.store(self.wi() - self.size, Ordering::Relaxed); }

Into

if self.wi() >= self.ri() + self.size { self.ri.store(self.wi() - self.size + 1, Ordering::Relaxed); }

Test Case

wi == 10, ri == 0, size == 10, item == y, buffer[0] == x, buffer[1] = z;

  1. pub.1. buffer[10 % 10] = item; <==> buffer[0] = y;
  2. sub.1. if 0 == 10 ==> not empty
  3. sub.2. item = buffer[0] <==> item = y;
  4. sub.3.a if 10 >= 0 + 10 => ri = 10 -10 +1 = 1; => begin loop again
  5. sub.2. item = buffer[1] <==> item = z;
  6. sub.3.a if 10 >= 1 + 10 => sub.3.b
  7. sub.3.b ri = 2; return z;

next value is returned, even if wi is incremented at any point the check at sub.3.a would catch it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants