When enqueuing an element and calling cond_broadcast all inside the lock, it doesn't really matter when exactly cond_broadcast is called, so while doing that before enqueuing the packet may look odd, it is not wrong in itself.
However, if one wants to wait until the queue is no longer overfull and does so by calling cond_wait after the potential call to cond_broadcast but before the actual enqueuing of the data, it means the cond_broadcast is no longer atomic with the update of the queue: cond_wait(cv,lk) is effectively an atomic unlock(lk)+wait(cv) followed by lock(lk).
It makes sense to wait before enqueuing, but then the wait operation should precede the broadcast.
Furthermore cond_wait can suffer from spurious wakeups - they seem to be really rare, and if so, they are harmless in this case. Still, it seems wiser to not proceed if there is no space in the queue.
When enqueuing an element and calling cond_broadcast all inside the lock, it doesn't really matter when exactly cond_broadcast is called, so while doing that before enqueuing the packet may look odd, it is not wrong in itself.
However, if one wants to wait until the queue is no longer overfull and does so by calling cond_wait after the potential call to cond_broadcast but before the actual enqueuing of the data, it means the cond_broadcast is no longer atomic with the update of the queue: cond_wait(cv,lk) is effectively an atomic unlock(lk)+wait(cv) followed by lock(lk).
It makes sense to wait before enqueuing, but then the wait operation should precede the broadcast.
Furthermore cond_wait can suffer from spurious wakeups - they seem to be really rare, and if so, they are harmless in this case. Still, it seems wiser to not proceed if there is no space in the queue.