blob: 91b5aa67c7d338e27c55a76a1bf698e214cfd414 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
libaxl_id_t
libaxl_generate_id(LIBAXL_CONTEXT *ctx)
{
LIBAXL_CONNECTION *conn = ctx->conn;
struct id_pool *pool = NULL, *next, *last;
uint32_t id;
pool = atomic_exchange(&conn->xid_pool, pool);
if (pool) {
id = pool->first;
pool->first += (uint32_t)1 << conn->xid_shift;
if (id == pool->last) {
next = pool->next;
if (next) {
free(pool);
pool = next;
}
next = NULL;
if (atomic_compare_exchange_strong(&conn->xid_pool, &next, pool))
return id;
if (!pool->next) {
free(pool);
return id;
}
}
while ((pool = atomic_exchange(&conn->xid_pool, pool))) {
for (last = pool; last->next; last = last->next);
last->next = atomic_exchange(&conn->xid_pool, NULL);
}
return id;
}
id = atomic_fetch_add(&conn->xid_last, 1);
if (id <= conn->xid_max)
return (id << conn->xid_shift) | conn->xid_base;
atomic_fetch_sub(&conn->xid_last, 1);
liberror_save_backtrace(NULL);
liberror_set_error("Request has been buffered and is ready to be sent",
"libaxl_generate_id", "libaxl", LIBAXL_ERROR_OUT_OF_RESOURCE_IDS);
return 0;
}
|