apr_status_t upload_progress_cache_init(apr_pool_t *pool, ServerConfig *config) { #if APR_HAS_SHARED_MEMORY apr_status_t result; apr_size_t size; upload_progress_cache_t *cache; apr_rmm_off_t block; if (config->cache_file) { /* Remove any existing shm segment with this name. */ apr_shm_remove(config->cache_file, config->pool); } size = APR_ALIGN_DEFAULT(config->cache_bytes); result = apr_shm_create(&config->cache_shm, size, config->cache_file, config->pool); if (result != APR_SUCCESS) { return result; } /* Determine the usable size of the shm segment. */ size = apr_shm_size_get(config->cache_shm); /* This will create a rmm "handler" to get into the shared memory area */ result = apr_rmm_init(&config->cache_rmm, NULL, apr_shm_baseaddr_get(config->cache_shm), size, config->pool); if (result != APR_SUCCESS) { return result; } apr_pool_cleanup_register(config->pool, config , upload_progress_cache_module_kill, apr_pool_cleanup_null); /* init cache object */ CACHE_LOCK(); block = apr_rmm_calloc(config->cache_rmm, sizeof(upload_progress_cache_t)); cache = block ? (upload_progress_cache_t *)apr_rmm_addr_get(config->cache_rmm, block) : NULL; if(cache == NULL) { CACHE_UNLOCK(); return 0; } cache->head = NULL; config->cache_offset = block; config->cache = cache; CACHE_UNLOCK(); #endif return APR_SUCCESS; }
static int upload_progress_handle_request(request_rec *r) { /**/up_log(APLOG_MARK, APLOG_DEBUG, 0, r->server, "upload_progress_handle_request()"); DirConfig* dir = (DirConfig*)ap_get_module_config(r->per_dir_config, &upload_progress_module); ServerConfig *config = get_server_config(r->server); if (dir && dir->track_enabled > 0) { if (r->method_number == M_POST) { int param_error; const char* id = get_progress_id(r, ¶m_error); if (id) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload id='%s' in trackable location: %s.", id, r->uri); CACHE_LOCK(); clean_old_connections(r); upload_progress_node_t *node = find_node(r, id); if (node == NULL) { node = insert_node(r, id); if (node) up_log(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Added upload with id='%s' to list.", id); } else if (node->done) { fill_new_upload_node_data(node, r); up_log(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Reused existing node with id='%s'.", id); } else { node = NULL; ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "Upload Progress: Upload with id='%s' already exists, ignoring.", id); } if (node) { upload_progress_context_t *ctx = (upload_progress_context_t*)apr_pcalloc(r->pool, sizeof(upload_progress_context_t)); ctx->node = node; ctx->r = r; apr_pool_cleanup_register(r->pool, ctx, upload_progress_cleanup, apr_pool_cleanup_null); ap_add_input_filter("UPLOAD_PROGRESS", NULL, r, r->connection); } CACHE_UNLOCK(); } else if (param_error < 0) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload with invalid ID in trackable location: %s.", r->uri); /* return HTTP_BAD_REQUEST; return HTTP_NOT_FOUND; */ } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload without ID in trackable location: %s.", r->uri); } } } return DECLINED; }
static void clean_old_connections(request_rec *r) { upload_progress_node_t *prev = NULL; ServerConfig *config = get_server_config(r); CACHE_LOCK(); upload_progress_node_t *node = fetch_first_node(config); while(node != NULL) { if(time(NULL) > node->expires && node->done == 1 && node->expires != -1) { /*clean*/ if(prev == NULL) { /* head */ upload_progress_cache_t *cache = fetch_cache(config); cache->head = fetch_node(config, node->next); cache_free(config, node->key); cache_free(config, node); node = cache->head; continue; } else { prev->next = node->next; cache_free(config, node->key); cache_free(config, node); node = prev; continue; } } prev = node; node = fetch_node(config, node->next); } CACHE_UNLOCK(); }
upload_progress_node_t* insert_node(request_rec *r, const char *key) { upload_progress_node_t *node; upload_progress_cache_t *cache; ServerConfig *config = (ServerConfig*)ap_get_module_config(r->server->module_config, &upload_progress_module); CACHE_LOCK(); upload_progress_node_t *head = fetch_first_node(config); node = store_node(config, key); if(head == NULL) { /* list is empty */ cache = fetch_cache(config); cache->head = node; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Inserted node into an empty list."); } else { upload_progress_node_t *tail = fetch_last_node(config); tail->next = node; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Inserted node at the end of the list."); } node->length = r->clength; node->received = 0; node->done = 0; node->err_status = 0; node->started_at = time(NULL); node->speed = 0; node->expires = -1; sscanf(apr_table_get(r->headers_in, "Content-Length"), "%d", &(node->length)); node->next = NULL; CACHE_UNLOCK(); return node; }
static int upload_progress_handle_request(request_rec *r) { DirConfig* dir = (DirConfig*)ap_get_module_config(r->per_dir_config, &upload_progress_module); ServerConfig *config = get_server_config(r); if(dir->track_enabled) { if(r->method_number == M_POST) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Upload in trackable location: %s.", r->uri); const char* id = get_progress_id(r); if(id != NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Progress id found: %s.", id); CACHE_LOCK(); upload_progress_node_t *node = find_node(r, id); CACHE_UNLOCK(); if(node == NULL) { add_upload_to_track(r, id); ap_add_input_filter("UPLOAD_PROGRESS", NULL, r, r->connection); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Node with id '%s' already exists.", id); } return DECLINED; } } } return DECLINED; }
int cache_table(char * sql, sqlite_cb cb, void * arg) { CACHE_LOCK(pcache); if (sql_process(pcache->db, sql, cb, arg) < 0) { log_error(LOG_NOTICE, "cache_table"); } CACHE_UNLOCK(pcache); return 0; }
int add_upload_to_track(request_rec* r, const char* key) { ServerConfig *config = get_server_config(r); upload_progress_node_t* node; clean_old_connections(r); CACHE_LOCK(); node = find_node(r, key); if(node == NULL) { node = insert_node(r, key); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Added upload with id=%s to list.", key); upload_progress_context_t *ctx = (upload_progress_context_t*)apr_pcalloc(r->pool, sizeof(upload_progress_context_t)); ctx->node = node; ctx->r = r; CACHE_UNLOCK(); apr_pool_cleanup_register(r->pool, ctx, upload_progress_cleanup, apr_pool_cleanup_null); return OK; } CACHE_UNLOCK(); return OK; }
static int track_upload_progress(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { apr_status_t rv; upload_progress_node_t *node; ServerConfig* config = get_server_config(f->r); if ((rv = ap_get_brigade(f->next, bb, mode, block, readbytes)) != APR_SUCCESS) { return rv; } apr_off_t length; apr_brigade_length(bb, 1, &length); const char* id = get_progress_id(f->r); if(id == NULL) return APR_SUCCESS; CACHE_LOCK(); node = find_node(f->r, id); CACHE_UNLOCK(); if(node == NULL) { return APR_SUCCESS; } else { CACHE_LOCK(); node->received += (int)length; int upload_time = time(NULL) - node->started_at; if(upload_time > 0) { node->speed = (int)(node->received / upload_time); } CACHE_UNLOCK(); } return APR_SUCCESS; }
int cache_search(TABLE_T table, char * sql, sqlite_cb cb, void * arg, SEARCH_T type) { int is_find = -1; char **azResult; char *zErrMsg; int nrow, ncolumn; int i; if (table >= TBL_NULL ) return is_find; CACHE_LOCK(pcache); do { if (sqlite3_get_table( pcache->db->sqlite_db , sql , &azResult , &nrow , &ncolumn , &zErrMsg)) { log_error(LOG_DEBUG, zErrMsg); break; } nrow += 1; if (cb == NULL) { if (nrow > 1) { is_find = 0; break; } is_find = -1; break; } for( i = 1 ; i < nrow ; i++ ) { cb(arg, ncolumn, azResult, azResult + (nrow * ncolumn)); is_find = 0; } //释放掉 azResult 的内存空间 sqlite3_free_table( azResult ); } while (0); CACHE_UNLOCK(pcache); return is_find; }
int cache_opt_item(TABLE_T table, char * sql) //插入 删除等操作 { int ret = -1; if (table >= TBL_NULL) return -1; //printf("\nxxx ret = %d\n", ret); CACHE_LOCK(pcache); do { if (sql_process(pcache->db, sql, NULL, NULL) < 0) { log_error(LOG_DEBUG, "sql_process"); break; } pcache->item_cnt++; ret = 0; } while (0); //printf("\nxxx ret = %d\n", ret); CACHE_UNLOCK(pcache); return ret; }
void D3DCacheFill(d3d_render_cache_system *pCacheSystem, d3d_render_pool_new *pPool, int numStages) { u_int curPacket, curChunk, count, indexOffset, numPackets; d3d_render_cache *pRenderCache = (d3d_render_cache *)pCacheSystem->curCache->data; d3d_render_packet_new *pPacket; d3d_render_chunk_new *pChunk; list_type list; CACHE_RESET(pRenderCache); CACHE_LOCK(pRenderCache); for (list = pPool->renderPacketList; list != pPool->curPacketList->next; list = list->next) { if (list == pPool->curPacketList) numPackets = pPool->curPacket; else numPackets = pPool->size; pPacket = (d3d_render_packet_new *)list->data; for (curPacket = 0; curPacket < numPackets; curPacket++, pPacket++) { for (curChunk = 0; curChunk < pPacket->curChunk; curChunk++) { pChunk = &pPacket->renderChunks[curChunk]; if ((pRenderCache->indexBuffer.curIndex + pChunk->numIndices) >= pRenderCache->size) { CACHE_UNLOCK(pRenderCache); pRenderCache = D3DCacheSystemSwap(pCacheSystem); if (NULL == pRenderCache) return; CACHE_LOCK(pRenderCache); } pChunk->pRenderCache = pRenderCache; pChunk->startIndex = pRenderCache->indexBuffer.curIndex; indexOffset = pRenderCache->xyzBuffer.curIndex; for (count = 0; count < pChunk->numVertices; count++) { CACHE_XYZ_ADD(pRenderCache, pChunk->xyz[count].x, pChunk->xyz[count].z, pChunk->xyz[count].y); switch (numStages) { case 1: CACHE_ST_ADD(pRenderCache, 0, pChunk->st0[count].s, pChunk->st0[count].t); break; case 2: CACHE_ST_ADD(pRenderCache, 0, pChunk->st0[count].s, pChunk->st0[count].t); CACHE_ST_ADD(pRenderCache, 1, pChunk->st1[count].s, pChunk->st1[count].t); break; } CACHE_BGRA_ADD(pRenderCache, pChunk->bgra[count].b, pChunk->bgra[count].g, pChunk->bgra[count].r, pChunk->bgra[count].a); } for (count = 0; count < pChunk->numIndices; count++) { CACHE_INDEX_ADD(pRenderCache, pChunk->indices[count] + indexOffset); } } } } if (pRenderCache) CACHE_UNLOCK(pRenderCache); }
void cache_release_db(void) { CACHE_UNLOCK(pcache); }
static int reportuploads_handler(request_rec *r) { int length, received, done, speed, err_status, found=0; char *response; DirConfig* dir = (DirConfig*)ap_get_module_config(r->per_dir_config, &upload_progress_module); if(!dir->report_enabled) { return DECLINED; } if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } /* get the tracking id if any */ const char *id = get_progress_id(r); if (id == NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Not found id in location with reports enabled. uri=%s", id, r->uri); return HTTP_NOT_FOUND; } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Found id=%s in location with reports enables. uri=%s", id, r->uri); } ServerConfig *config = (ServerConfig*)ap_get_module_config(r->server->module_config, &upload_progress_module); if (config->cache_rmm == NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Upload Progress: Cache error while generating report"); return HTTP_INTERNAL_SERVER_ERROR ; } CACHE_LOCK(); upload_progress_node_t *node = find_node(r, id); if (node != NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Node with id=%s found for report", id); received = node->received; length = node->length; done = node->done; speed = node->speed; err_status = node->err_status; found = 1; CACHE_UNLOCK(); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Node with id=%s not found for report", id); } CACHE_UNLOCK(); ap_set_content_type(r, "text/javascript"); apr_table_set(r->headers_out, "Expires", "Mon, 28 Sep 1970 06:00:00 GMT"); apr_table_set(r->headers_out, "Cache-Control", "no-cache"); /* There are 4 possibilities * request not yet started: found = false * request in error: err_status >= NGX_HTTP_SPECIAL_RESPONSE * request finished: done = true * request not yet started but registered: length==0 && rest ==0 * reauest in progress: rest > 0 */ if (!found) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'starting', 'uuid' : '%s' })", id); } else if (err_status >= HTTP_BAD_REQUEST ) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'error', 'status' : %d, 'uuid' : '%s' })", err_status, id); } else if (done) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'done', 'uuid' : '%s' })", id); } else if ( length == 0 && received == 0 ) { response = apr_psprintf(r->pool, "new Object({ 'state' : 'starting', 'uuid' : '%s' })", id); } else { response = apr_psprintf(r->pool, "new Object({ 'state' : 'uploading', 'received' : %d, 'size' : %d, 'speed' : %d, 'uuid' : '%s' })", received, length, speed, id); } char *completed_response; /* get the jsonp callback if any */ const char *jsonp = get_json_callback_param(r); // fix up response for jsonp request, if needed if (jsonp) { completed_response = apr_psprintf(r->pool, "%s(%s);\r\n", jsonp, response); } else { completed_response = apr_psprintf(r->pool, "%s\r\n", response); } ap_rputs(completed_response, r); return OK; }