/* blob= b_new(size) - create a new empty blob with space for size bytes */ INLINE blob_t * b_new(size_t size) { blob_t *b; b = malloc_or_die(sizeof(blob_t)); BLOB_NEXT_set(b, NULL); BLOB_REF_PTR_set(b, malloc_or_die(sizeof(_refcnt_blob_t) + size)); BLOB_REFCNT_set(b, 1); /* overwritten in enqueue_blob_for_transmision */ BLOB_BUF_SIZE_set(b, size); (void)get_time(&BLOB_RECEIVED_TIME(b)); return b; }
/* Peels off all the blobs which have been in the input queue for longer * than the spill limit, move them to the spill queue, and enqueue * them for eventual spilling or dropping. * * Note that the "spill queue" is used either for actual spilling (to the disk) * or dropping. * * Returns the number of (eventually) spilled (if spill enabled) or * dropped (if spill disabled) items. */ static stats_count_t spill_by_age(socket_worker_t * self, int spill_enabled, queue_t * private_queue, queue_t * spill_queue, uint64_t spill_microsec, struct timeval *now) { blob_t *cur_blob = private_queue->head; if (!cur_blob) return 0; /* If spill is disabled, this really counts the dropped packets. */ stats_count_t spilled = 0; if (elapsed_usec(&BLOB_RECEIVED_TIME(cur_blob), now) >= spill_microsec) { spill_queue->head = cur_blob; spill_queue->count = 1; while (BLOB_NEXT(cur_blob) && elapsed_usec(&BLOB_RECEIVED_TIME(BLOB_NEXT(cur_blob)), now) >= spill_microsec) { cur_blob = BLOB_NEXT(cur_blob); spill_queue->count++; } spill_queue->tail = cur_blob; private_queue->head = BLOB_NEXT(cur_blob); private_queue->count -= spill_queue->count; BLOB_NEXT_set(cur_blob, NULL); spilled += spill_queue->count; if (spill_enabled) { RELAY_ATOMIC_INCREMENT(self->counters.spilled_count, spill_queue->count); } else { RELAY_ATOMIC_INCREMENT(self->counters.dropped_count, spill_queue->count); } enqueue_queue_for_disk_writing(self, spill_queue); } return spilled; }
/* write a blob to disk */ static void write_blob_to_disk(disk_writer_t *self, blob_t *b) { assert(BLOB_REF_PTR(b)); setup_for_epoch(self, BLOB_RECEIVED_TIME(b).tv_sec); if ( self->fd >= 0 ) { ssize_t wrote= write(self->fd, BLOB_BUF(b), BLOB_BUF_SIZE(b)); if ( wrote == BLOB_BUF_SIZE(b) ) { RELAY_ATOMIC_INCREMENT( self->pcounters->disk_count, 1 ); return; } WARN_ERRNO("Wrote only %ld of %i bytes to '%s', error:", wrote, BLOB_BUF_SIZE(b), self->last_file_path); } RELAY_ATOMIC_INCREMENT( self->pcounters->disk_error_count, 1 ); }