int ngx_shmap_inc_double(ngx_shm_zone_t* zone, ngx_str_t* key,double d,uint32_t exptime,double* ret) { ngx_int_t rc = 0; ngx_str_t data = ngx_null_string; assert(zone != NULL); assert(key != NULL); assert(ret != NULL); uint8_t value_type = VT_DOUBLE; rc = ngx_shmap_get(zone, key, &data, &value_type, NULL,NULL); if(rc == 0){ if(value_type != VT_DOUBLE){ //NLOG_ERROR("key [%V] value_type [%d] invalid!",key, value_type); return -1; } double* p = (double*)data.data; //要改成原子操作 *ret = (*p += d); }else{ //不存在,插入新的 ngx_str_set_double(&data, &d); rc =ngx_shmap_set(zone, key, &data, value_type, exptime,0); if(rc == 0){ *ret = d; } } return rc; }
int ngx_shmap_inc_int(ngx_shm_zone_t* zone, ngx_str_t* key,int64_t i,uint32_t exptime, int64_t* ret) { assert(zone != NULL); assert(key != NULL); assert(ret != NULL); ngx_int_t rc = 0; ngx_str_t data = ngx_null_string; uint8_t value_type = VT_INT64; rc = ngx_shmap_get(zone, key, &data, &value_type, NULL,NULL); if(rc == 0){ if(value_type != VT_INT64){ //NLOG_ERROR("key [%V] value_type [%d] invalid!",key, value_type); return -1; } int64_t* p = (int64_t*)data.data; *ret = __sync_add_and_fetch(p, i); }else{ //不存在,插入新的 ngx_str_set_int64(&data, &i); rc =ngx_shmap_set(zone, key, &data, value_type, exptime,0); if(rc == 0){ *ret = i; } } return rc; }
int ngx_shmap_get_int64_and_clear(ngx_shm_zone_t* zone, ngx_str_t* key, int64_t* i) { uint8_t value_type = VT_NULL; ngx_str_t data = ngx_null_string; int ret = ngx_shmap_get(zone, key, &data, &value_type,NULL,NULL); if(ret == 0){ if(value_type != VT_INT64){ ret = -1; //NLOG_ERROR("ngx_shmap_get_int64(key=%V) return invalid value_type=%d",key, value_type); }else{ int64_t* p = (int64_t*)data.data; *i = __sync_fetch_and_and(p, 0); } } return ret; }
int ngx_shmap_get_int32(ngx_shm_zone_t* zone, ngx_str_t* key, int32_t* i) { uint8_t value_type = VT_NULL; ngx_str_t data = ngx_null_string; int ret = ngx_shmap_get(zone, key, &data, &value_type,NULL,NULL); if(ret == 0){ if(value_type != VT_INT32){ ret = -1; //NLOG_ERROR("ngx_shmap_get_int32(key=%V) return invalid value_type=%d",key, value_type); }else{ int32_t* p = (int32_t*)data.data; *i = *p; } } return ret; }
static ngx_int_t ngx_http_shmtest_get(ngx_http_request_t *r){ ngx_int_t rc = NGX_HTTP_OK; ngx_str_t key = ngx_null_string; ngx_str_t value = ngx_null_string; int32_t ikey = 0; uint8_t value_type = VT_BINARY; uint32_t exptime = 0; uint32_t user_flags = 0; if(ngx_http_arg(r, (u_char*)"key", 3, &key)!=NGX_OK){ NLOG_ERROR("get arg 'key' failed!"); return NGX_HTTP_BAD_REQUEST; } if(key.len > 2 && key.data[0] == '0' && key.data[1] == 'x'){ key.data += 2; key.len -= 2; ikey = ngx_hextoi(key.data, key.len); ngx_str_set_int32(&key, &ikey); NLOG_DEBUG("use int key ikey=%d", ikey); } shmtest_main_conf_t* smcf; smcf = ngx_http_get_module_main_conf(r, ngx_http_shmtest_module); if(smcf == NULL){ NLOG_ERROR("get module ngx_http_shmtest_module's main conf failed!"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_shm_zone_t* zone = smcf->shmap; u_char* rsp = ngx_pcalloc(r->connection->pool, 256); int rsp_len = 0; rc = ngx_shmap_get(zone, &key, &value, &value_type, &exptime, &user_flags); if(ikey != 0){ if(rc == 0){ rsp_len = ngx_sprintf(rsp, "get(%d)={value=%V,exptime=%d,user_flags=%d}!\n", ikey,&value,exptime,user_flags)-rsp; }else{ rsp_len = ngx_sprintf(rsp, "get(%d) failed!\n", ikey)-rsp; } }else{ if(rc == 0){ rsp_len = ngx_sprintf(rsp, "get(%V)={value=%V,exptime=%d,user_flags=%d}!\n", &key,&value,exptime,user_flags)-rsp; }else{ rsp_len = ngx_sprintf(rsp, "get(%V) failed!\n", &key)-rsp; } } ngx_chain_t* chain = ngx_http_shmtest_resp(r, (char*)rsp, rsp_len); if(chain != NULL){ r->headers_out.content_length_n = rsp_len; }else{ r->headers_out.content_length_n = 0; } rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { }else{ rc = ngx_http_output_filter(r, chain); } return rc; }