When you read from a default-constructed MPMCQueue, assert instead of SIGFPE.
authorMartin Martin <mcm@fb.com>
Sat, 12 Nov 2016 00:08:46 +0000 (16:08 -0800)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Sat, 12 Nov 2016 00:23:33 +0000 (16:23 -0800)
Summary:
I accidentally forgot to specify the capacity for my
MPMCQueue.  When I then did a blockingRead(), I got a SIGFPE.  Thanks
to a custom signal handler that doesn't print stack traces, and a few
more comedy of errors, I lost a day to this.  With this patch, I would
have gotten an assertion failure instead.

Reviewed By: yfeldblum

Differential Revision: D4169033

fbshipit-source-id: fab97ea0d5afc3c06885758b31a5e8c91ae75a45

folly/MPMCQueue.h

index 43e9eb210a7c4e9935306f45c03090beb1e0bab4..e706a1f49eafb89744f9490c65af9e11ab2fe567 100644 (file)
@@ -888,6 +888,7 @@ class MPMCQueueBase<Derived<T, Atom, Dynamic>> : boost::noncopyable {
 
   /// Same as blockingRead() but also records the ticket nunmer
   void blockingReadWithTicket(uint64_t& ticket, T& elem) noexcept {
+    assert(capacity_ != 0);
     ticket = popTicket_++;
     dequeueWithTicketBase(ticket, slots_, capacity_, stride_, elem);
   }
@@ -1065,6 +1066,7 @@ class MPMCQueueBase<Derived<T, Atom, Dynamic>> : boost::noncopyable {
   /// Maps an enqueue or dequeue ticket to the turn should be used at the
   /// corresponding SingleElementQueue
   uint32_t turn(uint64_t ticket, size_t cap) noexcept {
+    assert(cap != 0);
     return ticket / cap;
   }
 
@@ -1270,6 +1272,7 @@ class MPMCQueueBase<Derived<T, Atom, Dynamic>> : boost::noncopyable {
   void dequeueWithTicketBase(
     uint64_t ticket, Slot* slots, size_t cap, int stride, T& elem
   ) noexcept {
+    assert(cap != 0);
     slots[idx(ticket, cap, stride)]
       .dequeue(turn(ticket, cap),
                popSpinCutoff_,