Rizin
unix-like reverse engineering framework and cli tools
thread_queue.c File Reference
#include <rz_th.h>
#include "thread.h"

Go to the source code of this file.

Classes

struct  rz_th_queue_t
 RzThreadQueue is a thread-safe queue that can be listened on from multiple threads. More...
 

Functions

RZ_API RZ_OWN RzThreadQueuerz_th_queue_new (size_t max_size, RZ_NULLABLE RzListFree qfree)
 Allocates and initializes a new fifo queue. More...
 
RZ_API void rz_th_queue_free (RZ_NULLABLE RzThreadQueue *queue)
 Frees a RzThreadQueue structure. More...
 
RZ_API bool rz_th_queue_push (RZ_NONNULL RzThreadQueue *queue, RZ_NONNULL void *user, bool tail)
 Pushes a new element into the queue. More...
 
RZ_API RZ_OWN void * rz_th_queue_pop (RZ_NONNULL RzThreadQueue *queue, bool tail)
 Removes an element from the queue, but does not awaits when empty. More...
 
RZ_API RZ_OWN void * rz_th_queue_wait_pop (RZ_NONNULL RzThreadQueue *queue, bool tail)
 Removes an element from the queue, but yields the thread till not empty. More...
 
RZ_API bool rz_th_queue_is_empty (RZ_NONNULL RzThreadQueue *queue)
 Returns true if the queue is empty (thread-safe) More...
 
RZ_API bool rz_th_queue_is_full (RZ_NONNULL RzThreadQueue *queue)
 Returns true if the queue is full and when the size is not RZ_THREAD_QUEUE_UNLIMITED (thread-safe) More...
 

Function Documentation

◆ rz_th_queue_free()

RZ_API void rz_th_queue_free ( RZ_NULLABLE RzThreadQueue queue)

Frees a RzThreadQueue structure.

Parameters
queueThe RzThreadQueue to free

Definition at line 55 of file thread_queue.c.

55  {
56  if (!queue) {
57  return;
58  }
59 
60  rz_list_free(queue->list);
61  rz_th_lock_free(queue->lock);
62  rz_th_cond_free(queue->cond);
63  free(queue);
64 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_th_cond_free(RZ_NULLABLE RzThreadCond *cond)
Frees a RzThreadCond struct.
Definition: thread_cond.c:77
RZ_API void rz_th_lock_free(RZ_NULLABLE RzThreadLock *thl)
Frees a RzThreadLock structure.
Definition: thread_lock.c:89
uv_pipe_t queue
Definition: worker.c:9

References free(), queue, rz_list_free(), rz_th_cond_free(), and rz_th_lock_free().

Referenced by rz_bin_file_strings(), and rz_th_queue_new().

◆ rz_th_queue_is_empty()

RZ_API bool rz_th_queue_is_empty ( RZ_NONNULL RzThreadQueue queue)

Returns true if the queue is empty (thread-safe)

Parameters
queueThe RzThreadQueue to check
Returns
When empty returns true, otherwise false

Definition at line 148 of file thread_queue.c.

148  {
150 
151  rz_th_lock_enter(queue->lock);
152  bool is_empty = rz_list_empty(queue->list);
153  rz_th_lock_leave(queue->lock);
154  return is_empty;
155 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API void rz_th_lock_leave(RZ_NONNULL RzThreadLock *thl)
Releases a RzThreadLock structure.
Definition: thread_lock.c:75
RZ_API void rz_th_lock_enter(RZ_NONNULL RzThreadLock *thl)
Acquires a RzThreadLock structure.
Definition: thread_lock.c:45

References queue, rz_return_val_if_fail, rz_th_lock_enter(), and rz_th_lock_leave().

◆ rz_th_queue_is_full()

RZ_API bool rz_th_queue_is_full ( RZ_NONNULL RzThreadQueue queue)

Returns true if the queue is full and when the size is not RZ_THREAD_QUEUE_UNLIMITED (thread-safe)

Parameters
queueThe RzThreadQueue to check
Returns
When full returns true, otherwise false

Definition at line 164 of file thread_queue.c.

164  {
166 
167  rz_th_lock_enter(queue->lock);
168  bool is_full = queue->max_size != RZ_THREAD_QUEUE_UNLIMITED && rz_list_length(queue->list) >= queue->max_size;
169  rz_th_lock_leave(queue->lock);
170  return is_full;
171 }
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
#define RZ_THREAD_QUEUE_UNLIMITED
Definition: rz_th.h:20

References queue, rz_list_length(), rz_return_val_if_fail, rz_th_lock_enter(), rz_th_lock_leave(), and RZ_THREAD_QUEUE_UNLIMITED.

◆ rz_th_queue_new()

RZ_API RZ_OWN RzThreadQueue* rz_th_queue_new ( size_t  max_size,
RZ_NULLABLE RzListFree  qfree 
)

Allocates and initializes a new fifo queue.

Parameters
max_sizeThe maximum size of the queue, use RZ_THREAD_QUEUE_UNLIMITED for an unlimited size
qfreePointer to a custom free function to free the queue if not empty.
Returns
On success returns a valid pointer, otherwise NULL

Definition at line 32 of file thread_queue.c.

32  {
34  if (!queue) {
35  return NULL;
36  }
37 
38  queue->max_size = max_size;
39  queue->list = rz_list_newf(qfree);
40  queue->lock = rz_th_lock_new(false);
41  queue->cond = rz_th_cond_new();
42  if (!queue->list || !queue->lock || !queue->cond) {
44  return NULL;
45  }
46 
47  return queue;
48 }
#define NULL
Definition: cris-opc.c:27
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
#define RZ_NEW0(x)
Definition: rz_types.h:284
RzThreadQueue is a thread-safe queue that can be listened on from multiple threads.
Definition: thread_queue.c:17
RZ_API RZ_OWN RzThreadCond * rz_th_cond_new(void)
Condition variables are intended to be used to communicate changes in the state of data shared betwee...
Definition: thread_cond.c:13
RZ_API RZ_OWN RzThreadLock * rz_th_lock_new(bool recursive)
Allocates and initialize a RzThreadLock structure.
Definition: thread_lock.c:14
RZ_API void rz_th_queue_free(RZ_NULLABLE RzThreadQueue *queue)
Frees a RzThreadQueue structure.
Definition: thread_queue.c:55

References NULL, queue, rz_list_newf(), RZ_NEW0, rz_th_cond_new(), rz_th_lock_new(), and rz_th_queue_free().

Referenced by rz_bin_file_strings().

◆ rz_th_queue_pop()

RZ_API RZ_OWN void* rz_th_queue_pop ( RZ_NONNULL RzThreadQueue queue,
bool  tail 
)

Removes an element from the queue, but does not awaits when empty.

Parameters
queueThe RzThreadQueue to push to
tailWhen true, pops the element from the tail, otherwise from the head
Returns
On success returns a valid pointer, otherwise NULL

Definition at line 102 of file thread_queue.c.

102  {
104 
105  void *user = NULL;
106  rz_th_lock_enter(queue->lock);
107  if (tail) {
108  user = rz_list_pop(queue->list);
109  } else {
110  user = rz_list_pop_head(queue->list);
111  }
112  rz_th_lock_leave(queue->lock);
113  return user;
114 }
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
RZ_API RZ_OWN void * rz_list_pop_head(RZ_NONNULL RzList *list)
Removes and returns the first element of the list.
Definition: list.c:401

References NULL, queue, rz_list_pop(), rz_list_pop_head(), rz_return_val_if_fail, rz_th_lock_enter(), and rz_th_lock_leave().

Referenced by search_string_thread_runner().

◆ rz_th_queue_push()

RZ_API bool rz_th_queue_push ( RZ_NONNULL RzThreadQueue queue,
RZ_NONNULL void *  user,
bool  tail 
)

Pushes a new element into the queue.

Parameters
queueThe RzThreadQueue to push to
userThe non-null pointer to push to the queue
tailWhen true, appends the element to the tail, otherwise to the head
Returns
On success returns true, otherwise false

Definition at line 75 of file thread_queue.c.

75  {
76  rz_return_val_if_fail(queue && user, false);
77 
78  bool added = false;
79  rz_th_lock_enter(queue->lock);
80  if (!queue->max_size || rz_list_length(queue->list) < queue->max_size) {
81  if (tail) {
82  added = rz_list_append(queue->list, user) != NULL;
83  } else {
84  added = rz_list_prepend(queue->list, user) != NULL;
85  }
86  }
87  if (added) {
88  rz_th_cond_signal(queue->cond);
89  }
90  rz_th_lock_leave(queue->lock);
91  return added;
92 }
RZ_API RZ_BORROW RzListIter * rz_list_prepend(RZ_NONNULL RzList *list, void *data)
Appends at the beginning of the list a new element.
Definition: list.c:316
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_th_cond_signal(RZ_NONNULL RzThreadCond *cond)
This function shall unblock at least one of the threads that are blocked on the specified condition.
Definition: thread_cond.c:34

References NULL, queue, rz_list_append(), rz_list_length(), rz_list_prepend(), rz_return_val_if_fail, rz_th_cond_signal(), rz_th_lock_enter(), and rz_th_lock_leave().

Referenced by rz_bin_file_strings().

◆ rz_th_queue_wait_pop()

RZ_API RZ_OWN void* rz_th_queue_wait_pop ( RZ_NONNULL RzThreadQueue queue,
bool  tail 
)

Removes an element from the queue, but yields the thread till not empty.

Parameters
queueThe RzThreadQueue to push to
tailWhen true, pops the element from the tail, otherwise from the head
Returns
On success returns a valid pointer, otherwise NULL

Definition at line 124 of file thread_queue.c.

124  {
126 
127  void *user = NULL;
128  rz_th_lock_enter(queue->lock);
129  if (rz_list_empty(queue->list)) {
130  rz_th_cond_wait(queue->cond, queue->lock);
131  }
132  if (tail) {
133  user = rz_list_pop(queue->list);
134  } else {
135  user = rz_list_pop_head(queue->list);
136  }
137  rz_th_lock_leave(queue->lock);
138  return user;
139 }
RZ_API void rz_th_cond_wait(RZ_NONNULL RzThreadCond *cond, RZ_NONNULL RzThreadLock *lock)
The function shall block on a condition variable and shall be called with RzThreadLock locked by the ...
Definition: thread_cond.c:63

References NULL, queue, rz_list_pop(), rz_list_pop_head(), rz_return_val_if_fail, rz_th_cond_wait(), rz_th_lock_enter(), and rz_th_lock_leave().