@@ -319,6 +319,37 @@ ngx_stream_lua_shdict_expire(ngx_stream_lua_shdict_ctx_t *ctx, ngx_uint_t n)
319
319
}
320
320
321
321
322
+ static inline ngx_rbtree_node_t *
323
+ ngx_stream_lua_shdict_force_alloc (ngx_stream_lua_shdict_ctx_t * ctx , size_t size ,
324
+ int * forcible )
325
+ {
326
+ int i ;
327
+ ngx_rbtree_node_t * node ;
328
+
329
+ node = ngx_slab_alloc_locked (ctx -> shpool , size );
330
+ * forcible = 0 ;
331
+
332
+ if (node ) {
333
+ return node ;
334
+ }
335
+
336
+ for (i = 0 ; i < 30 ; i ++ ) {
337
+ if (ngx_stream_lua_shdict_expire (ctx , 0 ) == 0 ) {
338
+ break ;
339
+ }
340
+
341
+ * forcible = 1 ;
342
+
343
+ node = ngx_slab_alloc_locked (ctx -> shpool , size );
344
+ if (node ) {
345
+ return node ;
346
+ }
347
+ }
348
+
349
+ return NULL ;
350
+ }
351
+
352
+
322
353
void
323
354
ngx_stream_lua_inject_shdict_api (ngx_stream_lua_main_conf_t * lmcf , lua_State * L )
324
355
{
@@ -1235,7 +1266,7 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1235
1266
double num_value , int user_flags , int set_user_flags ,
1236
1267
long exptime , int match_flags , int * match , char * * errmsg , int * forcible )
1237
1268
{
1238
- int i , n , match_value ;
1269
+ int n , match_value ;
1239
1270
u_char c , oc , * p ;
1240
1271
uint32_t hash ;
1241
1272
ngx_int_t rc ;
@@ -1324,13 +1355,21 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1324
1355
dd ("lookup returns %d" , (int ) rc );
1325
1356
1326
1357
1327
- if ((match_flags || match_value ) &&
1328
- ((rc == NGX_DECLINED || rc == NGX_DONE ) ||
1329
- (match_flags && old_user_flags != (int ) sd -> user_flags ) ||
1330
- (match_value && (old_value_type != sd -> value_type ||
1331
- old_str_value_len != sd -> value_len ||
1332
- ngx_memcmp (old_str_value_buf , sd -> data + key_len ,
1333
- (size_t ) old_str_value_len )))))
1358
+ if (match_flags
1359
+ && (rc != NGX_OK || old_user_flags != (int ) sd -> user_flags ))
1360
+ {
1361
+ ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1362
+ * match = 1 ;
1363
+ return NGX_DECLINED ;
1364
+ }
1365
+
1366
+ if (match_value
1367
+ && (rc != NGX_OK
1368
+ || old_value_type != sd -> value_type
1369
+ || old_str_value_len != sd -> value_len
1370
+ || ngx_memcmp (old_str_value_buf , sd -> data + key_len ,
1371
+ (size_t ) old_str_value_len )
1372
+ ))
1334
1373
{
1335
1374
ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1336
1375
* match = 1 ;
@@ -1341,7 +1380,9 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1341
1380
if (value_type == LUA_TNIL && !set_user_flags ) {
1342
1381
goto remove ;
1343
1382
}
1383
+
1344
1384
if (set_user_flags && value_type == LUA_TNIL ) {
1385
+ /* Only set flag, leave value unchanged */
1345
1386
ngx_queue_remove (& sd -> queue );
1346
1387
ngx_queue_insert_head (& ctx -> sh -> lru_queue , & sd -> queue );
1347
1388
@@ -1366,14 +1407,13 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1366
1407
&& sd -> value_type != SHDICT_TLIST )
1367
1408
{
1368
1409
1369
- ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1410
+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1370
1411
"lua shared dict set: found old entry and value "
1371
1412
"size matched, reusing it" );
1372
1413
1373
1414
ngx_queue_remove (& sd -> queue );
1374
1415
ngx_queue_insert_head (& ctx -> sh -> lru_queue , & sd -> queue );
1375
1416
1376
-
1377
1417
if (exptime > 0 ) {
1378
1418
tp = ngx_timeofday ();
1379
1419
sd -> expires = (uint64_t ) tp -> sec * 1000 + tp -> msec
@@ -1383,7 +1423,7 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1383
1423
sd -> expires = 0 ;
1384
1424
}
1385
1425
1386
- if (set_user_flags ) {
1426
+ if (set_user_flags ) {
1387
1427
sd -> user_flags = user_flags ;
1388
1428
}
1389
1429
@@ -1398,12 +1438,13 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1398
1438
return NGX_OK ;
1399
1439
}
1400
1440
1401
- ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1441
+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1402
1442
"lua shared dict set: found old entry but value size "
1403
1443
"NOT matched, removing it first" );
1404
- if (!set_user_flags ) {
1444
+ if (!set_user_flags ) {
1405
1445
user_flags = sd -> user_flags ;
1406
1446
}
1447
+
1407
1448
remove :
1408
1449
1409
1450
if (sd -> value_type == SHDICT_TLIST ) {
@@ -1429,7 +1470,6 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1429
1470
ngx_rbtree_delete (& ctx -> sh -> rbtree , node );
1430
1471
1431
1472
ngx_slab_free_locked (ctx -> shpool , node );
1432
-
1433
1473
}
1434
1474
1435
1475
/* rc == NGX_DECLINED or value size unmatch */
@@ -1439,43 +1479,29 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
1439
1479
return NGX_OK ;
1440
1480
}
1441
1481
1442
- ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1482
+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1443
1483
"lua shared dict cas: creating a new entry" );
1444
1484
1445
1485
n = offsetof(ngx_rbtree_node_t , color )
1446
1486
+ offsetof(ngx_stream_lua_shdict_node_t , data )
1447
1487
+ key_len
1448
1488
+ str_value_len ;
1449
1489
1450
- node = ngx_slab_alloc_locked (ctx -> shpool , n );
1451
-
1452
- if (node == NULL ) {
1453
- ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1454
- "lua shared dict cas: overriding non-expired items "
1490
+ node = ngx_stream_lua_shdict_force_alloc (ctx , n , forcible );
1491
+ if (* forcible == 1 ) {
1492
+ ngx_log_debug2 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1493
+ "lua shared dict cas: overwrote non-expired items "
1455
1494
"due to memory shortage for entry \"%*s\"" , key_len ,
1456
1495
key );
1496
+ }
1457
1497
1458
- for (i = 0 ; i < 30 ; i ++ ) {
1459
- if (ngx_stream_lua_shdict_expire (ctx , 0 ) == 0 ) {
1460
- break ;
1461
- }
1462
-
1463
- * forcible = 1 ;
1464
-
1465
- node = ngx_slab_alloc_locked (ctx -> shpool , n );
1466
- if (node != NULL ) {
1467
- goto allocated ;
1468
- }
1469
- }
1470
-
1498
+ if (!node ) {
1471
1499
ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1472
1500
1473
1501
* errmsg = "no memory" ;
1474
1502
return NGX_ERROR ;
1475
1503
}
1476
1504
1477
- allocated :
1478
-
1479
1505
sd = (ngx_stream_lua_shdict_node_t * ) & node -> color ;
1480
1506
1481
1507
node -> key = hash ;
@@ -1512,7 +1538,7 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
1512
1538
u_char * old_str_value_buf , size_t old_str_value_len ,
1513
1539
double old_num_value , int old_user_flags , int * value_type ,
1514
1540
u_char * * str_value_buf , size_t * str_value_len , double * num_value ,
1515
- int * user_flags , int match_flags , int * match , char * * errmsg )
1541
+ int * user_flags , int match_flags , int * unmatch , char * * errmsg )
1516
1542
{
1517
1543
u_char oc ;
1518
1544
ngx_str_t name ;
@@ -1524,7 +1550,7 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
1524
1550
int match_value ;
1525
1551
1526
1552
* errmsg = NULL ;
1527
- * match = 0 ;
1553
+ * unmatch = 0 ;
1528
1554
1529
1555
ctx = zone -> data ;
1530
1556
name = ctx -> name ;
@@ -1561,7 +1587,7 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
1561
1587
}
1562
1588
1563
1589
#if (NGX_DEBUG )
1564
- ngx_log_debug3 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1590
+ ngx_log_debug3 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1565
1591
"fetching key \"%*s\" in shared dict \"%V\"" , key_len ,
1566
1592
key , & name );
1567
1593
#endif /* NGX_DEBUG */
@@ -1582,18 +1608,19 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
1582
1608
return NGX_OK ;
1583
1609
}
1584
1610
1585
-
1586
- /* rc == NGX_OK || (rc == NGX_DONE) */
1587
- if ((match_value || match_flags ) &&
1588
- (!match_flags || old_user_flags == (int ) sd -> user_flags ) &&
1589
- (!match_value || (old_value_type == sd -> value_type &&
1590
- old_str_value_len == sd -> value_len &&
1591
- !ngx_memcmp (old_str_value_buf , sd -> data + key_len ,
1592
- (size_t ) old_str_value_len ))))
1593
- {
1594
- ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1595
- * match = 1 ;
1596
- return NGX_DECLINED ;
1611
+ if (match_value || match_flags ) {
1612
+ if (!match_flags || old_user_flags == (int ) sd -> user_flags )
1613
+ {
1614
+ if (!match_value || (old_value_type == sd -> value_type &&
1615
+ old_str_value_len == sd -> value_len &&
1616
+ !ngx_memcmp (old_str_value_buf , sd -> data + key_len ,
1617
+ (size_t ) old_str_value_len )))
1618
+ {
1619
+ ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1620
+ * unmatch = 1 ;
1621
+ return NGX_DECLINED ;
1622
+ }
1623
+ }
1597
1624
}
1598
1625
1599
1626
* value_type = sd -> value_type ;
@@ -1687,7 +1714,7 @@ ngx_stream_lua_ffi_shdict_store(ngx_shm_zone_t *zone, int op, u_char *key,
1687
1714
size_t str_value_len , double num_value , long exptime , int user_flags ,
1688
1715
char * * errmsg , int * forcible )
1689
1716
{
1690
- int i , n ;
1717
+ int n ;
1691
1718
u_char c , * p ;
1692
1719
uint32_t hash ;
1693
1720
ngx_int_t rc ;
@@ -1879,43 +1906,26 @@ ngx_stream_lua_ffi_shdict_store(ngx_shm_zone_t *zone, int op, u_char *key,
1879
1906
+ key_len
1880
1907
+ str_value_len ;
1881
1908
1882
- node = ngx_slab_alloc_locked (ctx -> shpool , n );
1883
-
1884
- if (node == NULL ) {
1885
-
1886
- if (op & NGX_STREAM_LUA_SHDICT_SAFE_STORE ) {
1887
- ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1909
+ if (op & NGX_STREAM_LUA_SHDICT_SAFE_STORE ) {
1910
+ node = ngx_slab_alloc_locked (ctx -> shpool , n );
1888
1911
1889
- * errmsg = "no memory" ;
1890
- return NGX_ERROR ;
1891
- }
1892
-
1893
- ngx_log_debug2 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1894
- "lua shared dict set: overriding non-expired items "
1895
- "due to memory shortage for entry \"%*s\"" , key_len ,
1896
- key );
1897
-
1898
- for (i = 0 ; i < 30 ; i ++ ) {
1899
- if (ngx_stream_lua_shdict_expire (ctx , 0 ) == 0 ) {
1900
- break ;
1901
- }
1902
-
1903
- * forcible = 1 ;
1904
-
1905
- node = ngx_slab_alloc_locked (ctx -> shpool , n );
1906
- if (node != NULL ) {
1907
- goto allocated ;
1908
- }
1912
+ } else {
1913
+ node = ngx_stream_lua_shdict_force_alloc (ctx , n , forcible );
1914
+ if (* forcible ) {
1915
+ ngx_log_debug2 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
1916
+ "lua shared dict store: overwrote non-expired items "
1917
+ "due to memory shortage for entry \"%*s\"" , key_len ,
1918
+ key );
1909
1919
}
1920
+ }
1910
1921
1922
+ if (!node ) {
1911
1923
ngx_shmtx_unlock (& ctx -> shpool -> mutex );
1912
1924
1913
1925
* errmsg = "no memory" ;
1914
1926
return NGX_ERROR ;
1915
1927
}
1916
1928
1917
- allocated :
1918
-
1919
1929
sd = (ngx_stream_lua_shdict_node_t * ) & node -> color ;
1920
1930
1921
1931
node -> key = hash ;
0 commit comments