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; }
static ngx_int_t ngx_http_shmtest_add_or_update(ngx_http_request_t *r,int func){ ngx_int_t rc = NGX_HTTP_OK; ngx_str_t key = ngx_null_string; int32_t ikey = 0; ngx_str_t value = ngx_null_string; char* szFunc = funcs[func]; if(ngx_http_arg(r, (u_char*)"key", 3, &key)!=NGX_OK){ NLOG_ERROR("get arg 'key' failed!"); return NGX_HTTP_BAD_REQUEST; } if(ngx_http_arg(r, (u_char*)"value", 5, &value)!=NGX_OK){ NLOG_ERROR("get arg 'value' failed!"); return NGX_HTTP_BAD_REQUEST; } //如果key开始为0x 表示使用数字的KEY. 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); } uint64_t exptime = 0; ngx_str_t sexptime = ngx_null_string; if(ngx_http_arg(r, (u_char*)"exptime", 7, &sexptime)==NGX_OK){ exptime = ngx_parse_time(&sexptime, 1); } if(ikey != 0){ NLOG_DEBUG("%s(key=%d,value=%V,exptime=%d)", szFunc,ikey,&value,exptime); }else{ NLOG_DEBUG("%s(key=%V,value=%V,exptime=%d)", szFunc,&key,&value,exptime); } 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; int ret = 0; switch(func){ case FUNC_ADD: ret = ngx_shmap_add(zone, &key,&value,VT_STRING,exptime,0); break; case FUNC_SET: ret = ngx_shmap_set(zone, &key,&value,VT_STRING,exptime,0); break; case FUNC_REPLACE: ret = ngx_shmap_replace(zone, &key,&value,VT_STRING,exptime,0); break; default: NLOG_ERROR("un process type [%d]", func); return NGX_HTTP_BAD_REQUEST; } char* rsp = ngx_pcalloc(r->connection->pool, 256); int rsp_len = 0; if(ret == 0){ rsp_len = sprintf(rsp, "%s success!\n", szFunc); }else{ rsp_len = sprintf(rsp, "%s failed!\n", szFunc); } ngx_chain_t* chain = ngx_http_shmtest_resp(r, 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; }