queue.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. /*
  2. *
  3. * Embedded Linux library
  4. *
  5. * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #include "queue.h"
  26. #include "private.h"
  27. #include "useful.h"
  28. /**
  29. * SECTION:queue
  30. * @short_description: Queue support
  31. *
  32. * Queue support
  33. */
  34. /**
  35. * l_queue:
  36. *
  37. * Opague object representing the queue.
  38. */
  39. struct l_queue {
  40. struct l_queue_entry *head;
  41. struct l_queue_entry *tail;
  42. unsigned int entries;
  43. };
  44. /**
  45. * l_queue_new:
  46. *
  47. * Create a new queue.
  48. *
  49. * No error handling is needed since. In case of real memory allocation
  50. * problems abort() will be called.
  51. *
  52. * Returns: a newly allocated #l_queue object
  53. **/
  54. LIB_EXPORT struct l_queue *l_queue_new(void)
  55. {
  56. struct l_queue *queue;
  57. queue = l_new(struct l_queue, 1);
  58. queue->head = NULL;
  59. queue->tail = NULL;
  60. queue->entries = 0;
  61. return queue;
  62. }
  63. /**
  64. * l_queue_destroy:
  65. * @queue: queue object
  66. * @destroy: destroy function
  67. *
  68. * Free queue and call @destory on all remaining entries.
  69. **/
  70. LIB_EXPORT void l_queue_destroy(struct l_queue *queue,
  71. l_queue_destroy_func_t destroy)
  72. {
  73. l_queue_clear(queue, destroy);
  74. l_free(queue);
  75. }
  76. /**
  77. * l_queue_clear:
  78. * @queue: queue object
  79. * @destroy: destroy function
  80. *
  81. * Clear queue and call @destory on all remaining entries.
  82. **/
  83. LIB_EXPORT void l_queue_clear(struct l_queue *queue,
  84. l_queue_destroy_func_t destroy)
  85. {
  86. struct l_queue_entry *entry;
  87. if (unlikely(!queue))
  88. return;
  89. entry = queue->head;
  90. while (entry) {
  91. struct l_queue_entry *tmp = entry;
  92. if (destroy)
  93. destroy(entry->data);
  94. entry = entry->next;
  95. l_free(tmp);
  96. }
  97. queue->head = NULL;
  98. queue->tail = NULL;
  99. queue->entries = 0;
  100. }
  101. /**
  102. * l_queue_push_tail:
  103. * @queue: queue object
  104. * @data: pointer to data
  105. *
  106. * Adds @data pointer at the end of the queue.
  107. *
  108. * Returns: #true when data has been added and #false in case an invalid
  109. * @queue object has been provided
  110. **/
  111. LIB_EXPORT bool l_queue_push_tail(struct l_queue *queue, void *data)
  112. {
  113. struct l_queue_entry *entry;
  114. if (unlikely(!queue))
  115. return false;
  116. entry = l_new(struct l_queue_entry, 1);
  117. entry->data = data;
  118. entry->next = NULL;
  119. if (queue->tail)
  120. queue->tail->next = entry;
  121. queue->tail = entry;
  122. if (!queue->head)
  123. queue->head = entry;
  124. queue->entries++;
  125. return true;
  126. }
  127. /**
  128. * l_queue_push_head:
  129. * @queue: queue object
  130. * @data: pointer to data
  131. *
  132. * Adds @data pointer at the start of the queue.
  133. *
  134. * Returns: #true when data has been added and #false in case an invalid
  135. * @queue object has been provided
  136. **/
  137. LIB_EXPORT bool l_queue_push_head(struct l_queue *queue, void *data)
  138. {
  139. struct l_queue_entry *entry;
  140. if (unlikely(!queue))
  141. return false;
  142. entry = l_new(struct l_queue_entry, 1);
  143. entry->data = data;
  144. entry->next = queue->head;
  145. queue->head = entry;
  146. if (!queue->tail)
  147. queue->tail = entry;
  148. queue->entries++;
  149. return true;
  150. }
  151. /**
  152. * l_queue_pop_head:
  153. * @queue: queue object
  154. *
  155. * Removes the first element of the queue an returns it.
  156. *
  157. * Returns: data pointer to first element or #NULL in case an empty queue
  158. **/
  159. LIB_EXPORT void *l_queue_pop_head(struct l_queue *queue)
  160. {
  161. struct l_queue_entry *entry;
  162. void *data;
  163. if (unlikely(!queue))
  164. return NULL;
  165. if (!queue->head)
  166. return NULL;
  167. entry = queue->head;
  168. if (!queue->head->next) {
  169. queue->head = NULL;
  170. queue->tail = NULL;
  171. } else
  172. queue->head = queue->head->next;
  173. data = entry->data;
  174. l_free(entry);
  175. queue->entries--;
  176. return data;
  177. }
  178. /**
  179. * l_queue_peek_head:
  180. * @queue: queue object
  181. *
  182. * Peeks at the first element of the queue an returns it.
  183. *
  184. * Returns: data pointer to first element or #NULL in case an empty queue
  185. **/
  186. LIB_EXPORT void *l_queue_peek_head(struct l_queue *queue)
  187. {
  188. struct l_queue_entry *entry;
  189. if (unlikely(!queue))
  190. return NULL;
  191. if (!queue->head)
  192. return NULL;
  193. entry = queue->head;
  194. return entry->data;
  195. }
  196. /**
  197. * l_queue_peek_tail:
  198. * @queue: queue object
  199. *
  200. * Peeks at the last element of the queue an returns it.
  201. *
  202. * Returns: data pointer to first element or #NULL in case an empty queue
  203. **/
  204. LIB_EXPORT void *l_queue_peek_tail(struct l_queue *queue)
  205. {
  206. struct l_queue_entry *entry;
  207. if (unlikely(!queue))
  208. return NULL;
  209. if (!queue->tail)
  210. return NULL;
  211. entry = queue->tail;
  212. return entry->data;
  213. }
  214. /**
  215. * l_queue_insert:
  216. * @queue: queue object
  217. * @data: pointer to data
  218. * @function: compare function
  219. * @user_data: user data given to compare function
  220. *
  221. * Inserts @data pointer at a position in the queue determined by the
  222. * compare @function. @function should return >= 0 if the @data (first
  223. * parameter) should be inserted after the current entry (second parameter)
  224. * and should return < 0 if before it.
  225. *
  226. * Returns: #true when data has been added and #false in case of failure
  227. **/
  228. LIB_EXPORT bool l_queue_insert(struct l_queue *queue, void *data,
  229. l_queue_compare_func_t function, void *user_data)
  230. {
  231. struct l_queue_entry *entry, *prev, *cur;
  232. int cmp;
  233. if (unlikely(!queue || !function))
  234. return false;
  235. entry = l_new(struct l_queue_entry, 1);
  236. entry->data = data;
  237. entry->next = NULL;
  238. if (!queue->head) {
  239. queue->head = entry;
  240. queue->tail = entry;
  241. goto done;
  242. }
  243. for (prev = NULL, cur = queue->head; cur; prev = cur, cur = cur->next) {
  244. cmp = function(entry->data, cur->data, user_data);
  245. if (cmp >= 0)
  246. continue;
  247. if (prev == NULL) {
  248. entry->next = queue->head;
  249. queue->head = entry;
  250. goto done;
  251. }
  252. entry->next = cur;
  253. prev->next = entry;
  254. goto done;
  255. }
  256. queue->tail->next = entry;
  257. queue->tail = entry;
  258. done:
  259. queue->entries++;
  260. return true;
  261. }
  262. /**
  263. * l_queue_find:
  264. * @queue: queue object
  265. * @function: match function
  266. * @user_data: user data given to compare function
  267. *
  268. * Finds an entry in the queue by running the match @function
  269. *
  270. * Returns: Matching entry or NULL if no entry can be found
  271. **/
  272. LIB_EXPORT void *l_queue_find(struct l_queue *queue,
  273. l_queue_match_func_t function,
  274. const void *user_data)
  275. {
  276. struct l_queue_entry *entry;
  277. if (unlikely(!queue || !function))
  278. return NULL;
  279. for (entry = queue->head; entry; entry = entry->next)
  280. if (function(entry->data, user_data))
  281. return entry->data;
  282. return NULL;
  283. }
  284. /**
  285. * l_queue_remove:
  286. * @queue: queue object
  287. * @data: pointer to data
  288. *
  289. * Remove given @data from the queue.
  290. *
  291. * Returns: #true when data has been removed and #false when data could not
  292. * be found or an invalid @queue object has been provided
  293. **/
  294. LIB_EXPORT bool l_queue_remove(struct l_queue *queue, void *data)
  295. {
  296. struct l_queue_entry *entry, *prev;
  297. if (unlikely(!queue))
  298. return false;
  299. for (entry = queue->head, prev = NULL; entry;
  300. prev = entry, entry = entry->next) {
  301. if (entry->data != data)
  302. continue;
  303. if (prev)
  304. prev->next = entry->next;
  305. else
  306. queue->head = entry->next;
  307. if (!entry->next)
  308. queue->tail = prev;
  309. l_free(entry);
  310. queue->entries--;
  311. return true;
  312. }
  313. return false;
  314. }
  315. /**
  316. * l_queue_reverse:
  317. * @queue: queue object
  318. *
  319. * Reverse entries in the queue.
  320. *
  321. * Returns: #true on success and #false on failure
  322. **/
  323. LIB_EXPORT bool l_queue_reverse(struct l_queue *queue)
  324. {
  325. struct l_queue_entry *entry, *prev = NULL;
  326. if (unlikely(!queue))
  327. return false;
  328. entry = queue->head;
  329. while (entry) {
  330. struct l_queue_entry *next = entry->next;
  331. entry->next = prev;
  332. prev = entry;
  333. entry = next;
  334. }
  335. queue->tail = queue->head;
  336. queue->head = prev;
  337. return true;
  338. }
  339. /**
  340. * l_queue_foreach:
  341. * @queue: queue object
  342. * @function: callback function
  343. * @user_data: user data given to callback function
  344. *
  345. * Call @function for every given data in @queue.
  346. **/
  347. LIB_EXPORT void l_queue_foreach(struct l_queue *queue,
  348. l_queue_foreach_func_t function, void *user_data)
  349. {
  350. struct l_queue_entry *entry;
  351. if (unlikely(!queue || !function))
  352. return;
  353. for (entry = queue->head; entry; entry = entry->next)
  354. function(entry->data, user_data);
  355. }
  356. /**
  357. * l_queue_foreach_remove:
  358. * @queue: queue object
  359. * @function: callback function
  360. * @user_data: user data given to callback function
  361. *
  362. * Remove all entries in the @queue where @function returns #true.
  363. *
  364. * Returns: number of removed entries
  365. **/
  366. LIB_EXPORT unsigned int l_queue_foreach_remove(struct l_queue *queue,
  367. l_queue_remove_func_t function, void *user_data)
  368. {
  369. struct l_queue_entry *entry, *prev = NULL;
  370. unsigned int count = 0;
  371. if (unlikely(!queue || !function))
  372. return 0;
  373. entry = queue->head;
  374. while (entry) {
  375. if (function(entry->data, user_data)) {
  376. struct l_queue_entry *tmp = entry;
  377. if (prev)
  378. prev->next = entry->next;
  379. else
  380. queue->head = entry->next;
  381. if (!entry->next)
  382. queue->tail = prev;
  383. entry = entry->next;
  384. l_free(tmp);
  385. count++;
  386. } else {
  387. prev = entry;
  388. entry = entry->next;
  389. }
  390. }
  391. queue->entries -= count;
  392. return count;
  393. }
  394. /**
  395. * l_queue_remove_if
  396. * @queue: queue object
  397. * @function: callback function
  398. * @user_data: user data given to callback function
  399. *
  400. * Remove the first entry in the @queue where the function returns #true.
  401. *
  402. * Returns: NULL if no entry was found, or the entry data if removal was
  403. * successful.
  404. **/
  405. LIB_EXPORT void *l_queue_remove_if(struct l_queue *queue,
  406. l_queue_match_func_t function,
  407. const void *user_data)
  408. {
  409. struct l_queue_entry *entry, *prev = NULL;
  410. if (unlikely(!queue || !function))
  411. return NULL;
  412. entry = queue->head;
  413. while (entry) {
  414. if (function(entry->data, user_data)) {
  415. struct l_queue_entry *tmp = entry;
  416. void *data;
  417. if (prev)
  418. prev->next = entry->next;
  419. else
  420. queue->head = entry->next;
  421. if (!entry->next)
  422. queue->tail = prev;
  423. entry = entry->next;
  424. data = tmp->data;
  425. l_free(tmp);
  426. queue->entries--;
  427. return data;
  428. }
  429. prev = entry;
  430. entry = entry->next;
  431. }
  432. return NULL;
  433. }
  434. /**
  435. * l_queue_length:
  436. * @queue: queue object
  437. *
  438. * Returns: entries of the queue
  439. **/
  440. LIB_EXPORT unsigned int l_queue_length(struct l_queue *queue)
  441. {
  442. if (unlikely(!queue))
  443. return 0;
  444. return queue->entries;
  445. }
  446. /**
  447. * l_queue_isempty:
  448. * @queue: queue object
  449. *
  450. * Returns: #true if @queue is empty and #false is not
  451. **/
  452. LIB_EXPORT bool l_queue_isempty(struct l_queue *queue)
  453. {
  454. if (unlikely(!queue))
  455. return true;
  456. return queue->entries == 0;
  457. }
  458. /**
  459. * l_queue_get_entries:
  460. * @queue: queue object
  461. *
  462. * This function gives direct, read-only access to the internal list structure
  463. * of the queue. This can be used to efficiently traverse the elements.
  464. *
  465. * Returns: A pointer to the head of the queue.
  466. **/
  467. LIB_EXPORT const struct l_queue_entry *l_queue_get_entries(
  468. const struct l_queue *queue)
  469. {
  470. if (unlikely(!queue))
  471. return NULL;
  472. return queue->head;
  473. }