@@ -319,6 +319,37 @@ ngx_stream_lua_shdict_expire(ngx_stream_lua_shdict_ctx_t *ctx, ngx_uint_t n)
319319}
320320
321321
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+
322353void
323354ngx_stream_lua_inject_shdict_api (ngx_stream_lua_main_conf_t * lmcf , lua_State * L )
324355{
@@ -1235,7 +1266,7 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
12351266 double num_value , int user_flags , int set_user_flags ,
12361267 long exptime , int match_flags , int * match , char * * errmsg , int * forcible )
12371268{
1238- int i , n , match_value ;
1269+ int n , match_value ;
12391270 u_char c , oc , * p ;
12401271 uint32_t hash ;
12411272 ngx_int_t rc ;
@@ -1324,13 +1355,21 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
13241355 dd ("lookup returns %d" , (int ) rc );
13251356
13261357
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+ ))
13341373 {
13351374 ngx_shmtx_unlock (& ctx -> shpool -> mutex );
13361375 * match = 1 ;
@@ -1341,7 +1380,9 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
13411380 if (value_type == LUA_TNIL && !set_user_flags ) {
13421381 goto remove ;
13431382 }
1383+
13441384 if (set_user_flags && value_type == LUA_TNIL ) {
1385+ /* Only set flag, leave value unchanged */
13451386 ngx_queue_remove (& sd -> queue );
13461387 ngx_queue_insert_head (& ctx -> sh -> lru_queue , & sd -> queue );
13471388
@@ -1366,14 +1407,13 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
13661407 && sd -> value_type != SHDICT_TLIST )
13671408 {
13681409
1369- ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1410+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
13701411 "lua shared dict set: found old entry and value "
13711412 "size matched, reusing it" );
13721413
13731414 ngx_queue_remove (& sd -> queue );
13741415 ngx_queue_insert_head (& ctx -> sh -> lru_queue , & sd -> queue );
13751416
1376-
13771417 if (exptime > 0 ) {
13781418 tp = ngx_timeofday ();
13791419 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,
13831423 sd -> expires = 0 ;
13841424 }
13851425
1386- if (set_user_flags ) {
1426+ if (set_user_flags ) {
13871427 sd -> user_flags = user_flags ;
13881428 }
13891429
@@ -1398,12 +1438,13 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
13981438 return NGX_OK ;
13991439 }
14001440
1401- ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1441+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
14021442 "lua shared dict set: found old entry but value size "
14031443 "NOT matched, removing it first" );
1404- if (!set_user_flags ) {
1444+ if (!set_user_flags ) {
14051445 user_flags = sd -> user_flags ;
14061446 }
1447+
14071448remove :
14081449
14091450 if (sd -> value_type == SHDICT_TLIST ) {
@@ -1429,7 +1470,6 @@ ngx_stream_lua_ffi_shdict_cas(ngx_shm_zone_t *zone, u_char *key,
14291470 ngx_rbtree_delete (& ctx -> sh -> rbtree , node );
14301471
14311472 ngx_slab_free_locked (ctx -> shpool , node );
1432-
14331473 }
14341474
14351475 /* 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,
14391479 return NGX_OK ;
14401480 }
14411481
1442- ngx_log_debug0 (NGX_LOG_DEBUG_HTTP , ctx -> log , 0 ,
1482+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , ctx -> log , 0 ,
14431483 "lua shared dict cas: creating a new entry" );
14441484
14451485 n = offsetof(ngx_rbtree_node_t , color )
14461486 + offsetof(ngx_stream_lua_shdict_node_t , data )
14471487 + key_len
14481488 + str_value_len ;
14491489
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 "
14551494 "due to memory shortage for entry \"%*s\"" , key_len ,
14561495 key );
1496+ }
14571497
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 ) {
14711499 ngx_shmtx_unlock (& ctx -> shpool -> mutex );
14721500
14731501 * errmsg = "no memory" ;
14741502 return NGX_ERROR ;
14751503 }
14761504
1477- allocated :
1478-
14791505 sd = (ngx_stream_lua_shdict_node_t * ) & node -> color ;
14801506
14811507 node -> key = hash ;
@@ -1512,7 +1538,7 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
15121538 u_char * old_str_value_buf , size_t old_str_value_len ,
15131539 double old_num_value , int old_user_flags , int * value_type ,
15141540 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 )
15161542{
15171543 u_char oc ;
15181544 ngx_str_t name ;
@@ -1524,7 +1550,7 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
15241550 int match_value ;
15251551
15261552 * errmsg = NULL ;
1527- * match = 0 ;
1553+ * unmatch = 0 ;
15281554
15291555 ctx = zone -> data ;
15301556 name = ctx -> name ;
@@ -1561,7 +1587,7 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
15611587 }
15621588
15631589#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 ,
15651591 "fetching key \"%*s\" in shared dict \"%V\"" , key_len ,
15661592 key , & name );
15671593#endif /* NGX_DEBUG */
@@ -1582,18 +1608,19 @@ ngx_stream_lua_ffi_shdict_cog(ngx_shm_zone_t *zone,
15821608 return NGX_OK ;
15831609 }
15841610
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+ }
15971624 }
15981625
15991626 * 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,
16871714 size_t str_value_len , double num_value , long exptime , int user_flags ,
16881715 char * * errmsg , int * forcible )
16891716{
1690- int i , n ;
1717+ int n ;
16911718 u_char c , * p ;
16921719 uint32_t hash ;
16931720 ngx_int_t rc ;
@@ -1879,43 +1906,26 @@ ngx_stream_lua_ffi_shdict_store(ngx_shm_zone_t *zone, int op, u_char *key,
18791906 + key_len
18801907 + str_value_len ;
18811908
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 );
18881911
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 );
19091919 }
1920+ }
19101921
1922+ if (!node ) {
19111923 ngx_shmtx_unlock (& ctx -> shpool -> mutex );
19121924
19131925 * errmsg = "no memory" ;
19141926 return NGX_ERROR ;
19151927 }
19161928
1917- allocated :
1918-
19191929 sd = (ngx_stream_lua_shdict_node_t * ) & node -> color ;
19201930
19211931 node -> key = hash ;
0 commit comments