diff --git a/inc/librist.h b/inc/librist.h index 57ff046bcd73430dd74221efe722a39127d9a78f..f12ad407f0f1c2493ec81ea893ff1cab082c4b24 100755 --- a/inc/librist.h +++ b/inc/librist.h @@ -56,8 +56,8 @@ __BEGIN_DECLS /* Track PROTOCOL and API changes */ #define RIST_PROTOCOL_VERSION (2) -#define RIST_API_VERSION (7) -#define RIST_SUBVERSION (1) +#define RIST_API_VERSION (8) +#define RIST_SUBVERSION (0) #define RIST_PEER_CONFIG_VERSION (0) /* Default peer config values */ @@ -652,7 +652,7 @@ RIST_API int rist_receiver_oob_read(struct rist_receiver *ctx, const struct rist * @param ctx RIST receiver context * @param[out] data_block a pointer to the rist_data_block structure * @param timeout How long to wait for queue data (ms), 0 for no wait - * @return 0 on success, -1 on error + * @return num buffers remaining on queue +1 (0 if no buffer returned), -1 on error */ RIST_API int rist_receiver_data_read(struct rist_receiver *ctx, const struct rist_data_block **data_block, int timeout); diff --git a/src/rist.c b/src/rist.c index d91372d592e642146cc2773eea3aed5d52ecb080..61a1e932be095b32086799488f7abdf066ca6574 100644 --- a/src/rist.c +++ b/src/rist.c @@ -69,11 +69,23 @@ int rist_receiver_data_read(struct rist_receiver *ctx, const struct rist_data_bl } const struct rist_data_block *data_block = NULL; + /* We could enter the lock now, to read the counter. However performance penalties apply. + The risks for not entering the lock are either sleeping too much (a packet gets added while we read) + or not at all when we should (i.e.: the calling application is reading from multiple threads). Both + risks are tolerable */ + uint16_t num = ctx->dataout_fifo_queue_counter; + if (!num && timeout > 0) { + pthread_mutex_lock(&(ctx->mutex)); + pthread_cond_timedwait_ms(&(ctx->condition), &(ctx->mutex), timeout); + pthread_mutex_unlock(&(ctx->mutex)); + } pthread_rwlock_wrlock(&ctx->dataout_fifo_queue_lock); if (ctx->dataout_fifo_queue_read_index != ctx->dataout_fifo_queue_write_index) { data_block = ctx->dataout_fifo_queue[ctx->dataout_fifo_queue_read_index]; + //Now we are inside the lock, so the counter is now guarenteed to remain the same + num = ctx->dataout_fifo_queue_counter; ctx->dataout_fifo_queue_read_index = (ctx->dataout_fifo_queue_read_index + 1) % RIST_DATAOUT_QUEUE_BUFFERS; if (data_block) { @@ -85,16 +97,15 @@ int rist_receiver_data_read(struct rist_receiver *ctx, const struct rist_data_bl } pthread_rwlock_unlock(&ctx->dataout_fifo_queue_lock); - if (data_block == NULL && timeout > 0) + if (RIST_UNLIKELY(data_block == NULL && num > 0)) { - pthread_mutex_lock(&(ctx->mutex)); - pthread_cond_timedwait_ms(&(ctx->condition), &(ctx->mutex), timeout); - pthread_mutex_unlock(&(ctx->mutex)); + //I think this should never happen, should we consider this an error (-1 return code)? + num = 0; } *data_buffer = data_block; - return 0; + return num; } int rist_receiver_peer_create(struct rist_receiver *ctx,