Skip to content

Commit

Permalink
feat(error-utils): add flags to avoid data races problems
Browse files Browse the repository at this point in the history
  • Loading branch information
Tonidotpy committed Oct 2, 2023
1 parent e5fea48 commit bbc7e14
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
37 changes: 29 additions & 8 deletions error-utils/error_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ void error_utils_init(
handler->get_timeout = get_timeout;
handler->set_expire = set_expire;

handler->is_expire_invalidated = false;
handler->is_expired_on_invalidation = false;

// Init error instances
for (size_t i = 0; i < handler->buffer_size; i++) {
handler->errors[i].error = ERROR_UTILS_INVALID_INT;
Expand All @@ -319,7 +322,6 @@ void error_utils_init(
handler->errors[i].is_running = false;
handler->errors[i].heap_id = ERROR_UTILS_INVALID_INT;
handler->errors[i].timestamp = 0;
handler->errors[i].is_dead = false;
handler->errors[i].string_instance = false;

handler->expiring[i] = NULL;
Expand Down Expand Up @@ -365,18 +367,27 @@ bool error_utils_set(
err->is_expired = false;
err->is_running = true;
err->timestamp = handler->get_timestamp();
err->is_dead = false;

// Update handler
++(handler->running);

// Invalidate expire
handler->is_expire_invalidated = true;

// Update heap
_error_utils_heap_insert(handler, err);

// Update error expire handler if the new error is the first that will expire
if (handler->set_expire != NULL && _error_utils_heap_min(handler) == err)
handler->set_expire(err->timestamp, handler->get_timeout(error));

// Resume expire function
handler->is_expire_invalidated = false;
if (handler->is_expired_on_invalidation) {
handler->is_expired_on_invalidation = false;
error_utils_expire_errors(handler);
}

return true;
}
bool error_utils_reset(
Expand Down Expand Up @@ -409,41 +420,51 @@ bool error_utils_reset(
if (off == handler->buffer_size)
return true;

// Set the dead bit of the error
err->is_dead = true;
// Invalidate expire
handler->is_expire_invalidated = true;

ErrorUtilsRunningInstance * min = _error_utils_heap_min(handler);

// Remove error from heap
_error_utils_heap_remove(handler, err);

// Update error expire handler if the removed error will be the first to expire
if (handler->set_expire != NULL && handler->expiring[0] != min)
if (handler->set_expire != NULL && handler->expiring[0] != min) {
handler->set_expire((handler->expiring[0])->timestamp, handler->get_timeout((handler->expiring[0])->error));
handler->is_expired_on_invalidation = false;
}

// Update handler
--(handler->running);

// Resume expire function
handler->is_expire_invalidated = false;
if (handler->is_expired_on_invalidation) {
handler->is_expired_on_invalidation = false;
error_utils_expire_errors(handler);
}

// Update error
err->error = ERROR_UTILS_INVALID_INT;
err->instance.i = ERROR_UTILS_INVALID_INT;
err->is_expired = false;
err->is_running = false;
err->heap_id = ERROR_UTILS_INVALID_INT;
err->timestamp = 0;
err->is_dead = 0;

return true;
}
// TODO: Expire multiple errors
void error_utils_expire_errors(ErrorUtilsHandler * handler) {
if (handler == NULL)
return;
if (handler->is_expire_invalidated) {
handler->is_expired_on_invalidation = true;
return;
}

// Get expired error
ErrorUtilsRunningInstance * err = _error_utils_heap_min(handler);
if (err->is_dead)
return;

// Remove error from heap
_error_utils_heap_remove(handler, err);
Expand Down
4 changes: 3 additions & 1 deletion error-utils/error_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ typedef struct {
size_t heap_id;
bool is_expired : 1;
bool is_running : 1;
bool is_dead : 1; // If set to 1 the error cannot expire until it is reset to 0
bool string_instance : 1; // If true the instance is a string, otherwise it is an integer
} ErrorUtilsRunningInstance;

Expand All @@ -161,6 +160,9 @@ typedef struct {
ErrorUtilsTimestampCallback get_timestamp;
ErrorUtilsTimeoutCallback get_timeout;
ErrorUtilsExpireUpdateCallback set_expire;

bool is_expire_invalidated : 1; // Flag that invalidate the next function call to the expire callback
bool is_expired_on_invalidation : 1; // Flag set to true when the expire callback is called
} ErrorUtilsHandler;


Expand Down

0 comments on commit bbc7e14

Please sign in to comment.