1368
#ifndef NGX_HTTP_LUA_NO_FFI_API
1370
ngx_http_lua_ffi_shdict_store(ngx_shm_zone_t *zone, int op, u_char *key,
1371
size_t key_len, int value_type, u_char *str_value_buf,
1372
size_t str_value_len, double num_value, int exptime, int user_flags,
1373
char **errmsg, int *forcible)
1380
ngx_rbtree_node_t *node;
1381
ngx_http_lua_shdict_ctx_t *ctx;
1382
ngx_http_lua_shdict_node_t *sd;
1388
dd("exptime: %d", exptime);
1394
hash = ngx_crc32_short(key, key_len);
1396
switch (value_type) {
1402
dd("num value: %lf", num_value);
1403
str_value_buf = (u_char *) &num_value;
1404
str_value_len = sizeof(double);
1408
c = num_value ? 1 : 0;
1410
str_value_len = sizeof(u_char);
1414
if (op & (NGX_HTTP_LUA_SHDICT_ADD|NGX_HTTP_LUA_SHDICT_REPLACE)) {
1415
*errmsg = "attempt to add or replace nil values";
1419
str_value_buf = NULL;
1424
*errmsg = "unsupported value type";
1428
ngx_shmtx_lock(&ctx->shpool->mutex);
1431
ngx_http_lua_shdict_expire(ctx, 1);
1434
rc = ngx_http_lua_shdict_lookup(zone, hash, key, key_len, &sd);
1436
dd("lookup returns %d", (int) rc);
1438
if (op & NGX_HTTP_LUA_SHDICT_REPLACE) {
1440
if (rc == NGX_DECLINED || rc == NGX_DONE) {
1441
ngx_shmtx_unlock(&ctx->shpool->mutex);
1442
*errmsg = "not found";
1443
return NGX_DECLINED;
1450
if (op & NGX_HTTP_LUA_SHDICT_ADD) {
1453
ngx_shmtx_unlock(&ctx->shpool->mutex);
1455
return NGX_DECLINED;
1458
if (rc == NGX_DONE) {
1459
/* exists but expired */
1461
dd("go to replace");
1465
/* rc == NGX_DECLINED */
1471
if (rc == NGX_OK || rc == NGX_DONE) {
1473
if (value_type == LUA_TNIL) {
1478
if (str_value_buf && str_value_len == (size_t) sd->value_len) {
1480
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1481
"lua shared dict set: found old entry and value "
1482
"size matched, reusing it");
1484
ngx_queue_remove(&sd->queue);
1485
ngx_queue_insert_head(&ctx->sh->queue, &sd->queue);
1487
sd->key_len = (u_short) key_len;
1490
tp = ngx_timeofday();
1491
sd->expires = (uint64_t) tp->sec * 1000 + tp->msec
1492
+ (uint64_t) exptime;
1498
sd->user_flags = user_flags;
1500
sd->value_len = (uint32_t) str_value_len;
1502
dd("setting value type to %d", value_type);
1504
sd->value_type = (uint8_t) value_type;
1506
p = ngx_copy(sd->data, key, key_len);
1507
ngx_memcpy(p, str_value_buf, str_value_len);
1509
ngx_shmtx_unlock(&ctx->shpool->mutex);
1514
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1515
"lua shared dict set: found old entry bug value size "
1516
"NOT matched, removing it first");
1519
ngx_queue_remove(&sd->queue);
1521
node = (ngx_rbtree_node_t *)
1522
((u_char *) sd - offsetof(ngx_rbtree_node_t, color));
1524
ngx_rbtree_delete(&ctx->sh->rbtree, node);
1526
ngx_slab_free_locked(ctx->shpool, node);
1531
/* rc == NGX_DECLINED or value size unmatch */
1533
if (str_value_buf == NULL) {
1534
ngx_shmtx_unlock(&ctx->shpool->mutex);
1538
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1539
"lua shared dict set: creating a new entry");
1541
n = offsetof(ngx_rbtree_node_t, color)
1542
+ offsetof(ngx_http_lua_shdict_node_t, data)
1546
node = ngx_slab_alloc_locked(ctx->shpool, n);
1550
if (op & NGX_HTTP_LUA_SHDICT_SAFE_STORE) {
1551
ngx_shmtx_unlock(&ctx->shpool->mutex);
1553
*errmsg = "no memory";
1557
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1558
"lua shared dict set: overriding non-expired items "
1559
"due to memory shortage for entry \"%*s\"", key_len,
1562
for (i = 0; i < 30; i++) {
1563
if (ngx_http_lua_shdict_expire(ctx, 0) == 0) {
1569
node = ngx_slab_alloc_locked(ctx->shpool, n);
1575
ngx_shmtx_unlock(&ctx->shpool->mutex);
1577
*errmsg = "no memory";
1582
sd = (ngx_http_lua_shdict_node_t *) &node->color;
1585
sd->key_len = (u_short) key_len;
1588
tp = ngx_timeofday();
1589
sd->expires = (uint64_t) tp->sec * 1000 + tp->msec
1590
+ (uint64_t) exptime;
1596
sd->user_flags = user_flags;
1597
sd->value_len = (uint32_t) str_value_len;
1598
dd("setting value type to %d", value_type);
1599
sd->value_type = (uint8_t) value_type;
1601
p = ngx_copy(sd->data, key, key_len);
1602
ngx_memcpy(p, str_value_buf, str_value_len);
1604
ngx_rbtree_insert(&ctx->sh->rbtree, node);
1605
ngx_queue_insert_head(&ctx->sh->queue, &sd->queue);
1606
ngx_shmtx_unlock(&ctx->shpool->mutex);
1613
ngx_http_lua_ffi_shdict_get(ngx_shm_zone_t *zone, u_char *key,
1614
size_t key_len, int *value_type, u_char **str_value_buf,
1615
size_t *str_value_len, double *num_value, int *user_flags,
1616
int get_stale, int *is_stale)
1621
ngx_http_lua_shdict_ctx_t *ctx;
1622
ngx_http_lua_shdict_node_t *sd;
1632
hash = ngx_crc32_short(key, key_len);
1635
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1636
"fetching key \"%*s\" in shared dict \"%V\"", key_len,
1638
#endif /* NGX_DEBUG */
1640
ngx_shmtx_lock(&ctx->shpool->mutex);
1644
ngx_http_lua_shdict_expire(ctx, 1);
1648
rc = ngx_http_lua_shdict_lookup(zone, hash, key, key_len, &sd);
1650
dd("shdict lookup returns %d", (int) rc);
1652
if (rc == NGX_DECLINED || (rc == NGX_DONE && !get_stale)) {
1653
ngx_shmtx_unlock(&ctx->shpool->mutex);
1654
*value_type = LUA_TNIL;
1658
/* rc == NGX_OK || (rc == NGX_DONE && get_stale) */
1660
*value_type = sd->value_type;
1662
dd("data: %p", sd->data);
1663
dd("key len: %d", (int) sd->key_len);
1665
value.data = sd->data + sd->key_len;
1666
value.len = (size_t) sd->value_len;
1668
if (*str_value_len < (size_t) value.len) {
1669
if (*value_type != LUA_TSTRING) {
1673
*str_value_buf = malloc(value.len);
1674
if (*str_value_buf == NULL) {
1675
ngx_shmtx_unlock(&ctx->shpool->mutex);
1680
*str_value_len = value.len;
1682
switch (*value_type) {
1684
ngx_memcpy(*str_value_buf, value.data, value.len);
1689
if (value.len != sizeof(double)) {
1690
ngx_shmtx_unlock(&ctx->shpool->mutex);
1691
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
1692
"bad lua number value size found for key %*s "
1693
"in shared_dict %V: %z", key_len, key,
1698
*num_value = *(double *) value.data;
1703
if (value.len != sizeof(u_char)) {
1704
ngx_shmtx_unlock(&ctx->shpool->mutex);
1705
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
1706
"bad lua boolean value size found for key %*s "
1707
"in shared_dict %V: %z", key_len, key, &name,
1712
ngx_memcpy(*str_value_buf, value.data, value.len);
1717
ngx_shmtx_unlock(&ctx->shpool->mutex);
1718
ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
1719
"bad value type found for key %*s in "
1720
"shared_dict %V: %d", key_len, key, &name,
1724
*user_flags = sd->user_flags;
1725
dd("user flags: %d", *user_flags);
1727
ngx_shmtx_unlock(&ctx->shpool->mutex);
1731
/* always return value, flags, stale */
1733
*is_stale = (rc == NGX_DONE);
1742
ngx_http_lua_ffi_shdict_incr(ngx_shm_zone_t *zone, u_char *key,
1743
size_t key_len, double *value, char **err)
1747
ngx_http_lua_shdict_ctx_t *ctx;
1748
ngx_http_lua_shdict_node_t *sd;
1753
hash = ngx_crc32_short(key, key_len);
1755
dd("looking up key %.*s in shared dict %.*s", (int) key_len, key,
1756
(int) ctx->name.len, ctx->name.data);
1758
ngx_shmtx_lock(&ctx->shpool->mutex);
1760
ngx_http_lua_shdict_expire(ctx, 1);
1762
rc = ngx_http_lua_shdict_lookup(zone, hash, key, key_len, &sd);
1764
dd("shdict lookup returned %d", (int) rc);
1766
if (rc == NGX_DECLINED || rc == NGX_DONE) {
1767
ngx_shmtx_unlock(&ctx->shpool->mutex);
1774
if (sd->value_type != LUA_TNUMBER || sd->value_len != sizeof(double)) {
1775
ngx_shmtx_unlock(&ctx->shpool->mutex);
1776
*err = "not a number";
1780
ngx_queue_remove(&sd->queue);
1781
ngx_queue_insert_head(&ctx->sh->queue, &sd->queue);
1783
dd("setting value type to %d", (int) sd->value_type);
1785
p = sd->data + key_len;
1787
num = *(double *) p;
1790
ngx_memcpy(p, (double *) &num, sizeof(double));
1792
ngx_shmtx_unlock(&ctx->shpool->mutex);
1797
#endif /* NGX_HTTP_LUA_NO_FFI_API */
1312
1800
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */