APU_DECLARE(apr_status_t) apr_reslist_acquire(apr_reslist_t *reslist, void **resource) { apr_status_t rv; apr_res_t *res; apr_thread_mutex_lock(reslist->listlock); /* If there are idle resources on the available list, use * them right away. */ if (reslist->nidle > 0) { /* Pop off the first resource */ res = pop_resource(reslist); *resource = res->opaque; free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return APR_SUCCESS; } /* If we've hit our max, block until we're allowed to create * a new one, or something becomes free. */ else while (reslist->ntotal >= reslist->hmax && reslist->nidle <= 0) { if (reslist->timeout) { if ((rv = apr_thread_cond_timedwait(reslist->avail, reslist->listlock, reslist->timeout)) != APR_SUCCESS) { apr_thread_mutex_unlock(reslist->listlock); return rv; } } else apr_thread_cond_wait(reslist->avail, reslist->listlock); } /* If we popped out of the loop, first try to see if there * are new resources available for immediate use. */ if (reslist->nidle > 0) { res = pop_resource(reslist); *resource = res->opaque; free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return APR_SUCCESS; } /* Otherwise the reason we dropped out of the loop * was because there is a new slot available, so create * a resource to fill the slot and use it. */ else { rv = create_resource(reslist, &res); if (rv == APR_SUCCESS) { reslist->ntotal++; *resource = res->opaque; } free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return rv; } }
static apr_status_t reslist_cleanup(void *data_) { apr_status_t rv; apr_reslist_t *rl = data_; apr_res_t *res; apr_thread_mutex_lock(rl->listlock); while (rl->nidle > 0) { res = pop_resource(rl); rl->ntotal--; rv = destroy_resource(rl, res); if (rv != APR_SUCCESS) { return rv; } free_container(rl, res); } assert(rl->nidle == 0); assert(rl->ntotal == 0); apr_thread_mutex_destroy(rl->listlock); apr_thread_cond_destroy(rl->avail); return APR_SUCCESS; }
int main() { IntContainer *z; uint64_t val; z = malloc(sizeof(IntContainer)); z->x = (uint64_t) z; free_container(z); free(z); return 0; }
/* * We must ensure a container is either in the buffer or written to disks. */ static void* append_thread(void *arg) { while (1) { struct container *c = sync_queue_get_top(container_buffer); if (c == NULL) break; TIMER_DECLARE(1); TIMER_BEGIN(1); write_container(c); TIMER_END(1, jcr.write_time); sync_queue_pop(container_buffer); free_container(c); } return NULL; }
int send_data_from_obj(struct request *rq, struct mem_obj *obj) { struct buff * tmp=NULL;//obj->container; struct av *header=obj->headers; struct buff *hdrs_to_send=alloc_buff(CHUNK_SIZE); /* most headers fit this (?) */ // rq->server->set_time(60); char tmp_str[100]; int start=0,send_len=obj->content_length; pthread_mutex_lock(&obj->lock); if(!swap_in_obj(obj) ) { pthread_mutex_unlock(&obj->lock); dead_obj(obj); goto error; } pthread_mutex_unlock(&obj->lock); tmp=obj->container; if(rq->range_to==-1) rq->range_to=obj->content_length-1; if ( TEST(rq->flags, RQ_HAVE_RANGE)) { if( // && (obj->state == OBJ_READY) // && !content_chunked(obj) ((rq->range_from >= 0 && rq->range_from<obj->content_length-1) && (rq->range_to == -1||rq->range_to>rq->range_from) )) { attach_av_pair_to_buff("HTTP/1.1","206 Partial Content",hdrs_to_send); memset(tmp_str,0,sizeof(tmp_str)); snprintf(tmp_str,sizeof(tmp_str)-1,"%d-%d/%d",rq->range_from,rq->range_to,obj->content_length); /* if(rq->range_to!=-1) snprintf(tmp_str+strlen(tmp_str),sizeof(tmp_str)-1-strlen(tmp_str),"%d",MIN(rq->range_to,obj->content_length-1)); snprintf(tmp_str+strlen(tmp_str),sizeof(tmp_str)-1-strlen(tmp_str),"/%d",obj->content_length); */ attach_av_pair_to_buff("Content-Range:",tmp_str,hdrs_to_send); header=header->next; start=rq->range_from; if(rq->range_to>=0) send_len=MIN(rq->range_to+1,obj->content_length)-rq->range_from; else send_len=obj->content_length-rq->range_from; } else if(rq->range_from>obj->content_length-1) { attach_av_pair_to_buff("HTTP/1.1","416 Requested Range Not Satisfiable",hdrs_to_send); memset(tmp_str,0,sizeof(tmp_str)); snprintf(tmp_str,sizeof(tmp_str)-1,"*/%d",obj->content_length); attach_av_pair_to_buff("Content-Range:",tmp_str,hdrs_to_send); start=-1; header=header->next; } } while(header) { // printf("attr=%s\n",header->attr); if(strncasecmp(header->attr,"Connection:",11)==0) { if(!TEST(rq->flags,RQ_HAS_KEEP_CONNECTION)) { attach_av_pair_to_buff("Connection:","close",hdrs_to_send); } else { attach_av_pair_to_buff("Connection:","keep-alive",hdrs_to_send); } goto next_head; } if(strncasecmp(header->attr,"Server:",7)==0) { memset(tmp_str,0,sizeof(tmp_str)); snprintf(tmp_str,sizeof(tmp_str)-1,"kingate/%s (cached)",VER_ID); attach_av_pair_to_buff("Server:",tmp_str,hdrs_to_send); goto next_head; } attach_av_pair_to_buff(header->attr, header->val, hdrs_to_send); next_head: header = header->next; } attach_av_pair_to_buff("", "", hdrs_to_send); if(rq->server->send(hdrs_to_send->data,hdrs_to_send->used)<=0) goto done; // printf("start=%d,send_len=%d.\n",start,send_len); if(start==-1) goto done; while(tmp!=NULL) { if(tmp->used<start) { start-=tmp->used; goto next_buffer; } if(send_len<=0) break; if(rq->server->send(tmp->data+start,MIN(tmp->used,send_len))<=0) goto error; start=0; send_len-=tmp->used; next_buffer: tmp=tmp->next; } done: if(hdrs_to_send) free_container(hdrs_to_send); return SEND_FROM_MEM_OK; error: if(hdrs_to_send) free_container(hdrs_to_send); return CONNECT_ERR; }
static int load_head(struct request *rq,struct mem_obj *obj,head_info &m_head) { //char *answer = NULL; struct server_answ answ_state; struct pollarg pollarg[2]; struct av *header = NULL; int r=0,downgrade_flags=0; char *answer= (char *)malloc(ANSW_SIZE+1); char *buf=answer; int len=ANSW_SIZE; int head_status=CONNECT_ERR; struct buff *hdrs_to_send=NULL; // rq->client->set_time(0); // rq->server->set_time(0); if ( !answer ) goto error; memset(&answ_state,0, sizeof(answ_state)); pollarg[0].fd = rq->client->get_socket(); pollarg[0].request = FD_POLL_RD; pollarg[1].fd = rq->server->get_socket(); pollarg[1].request = FD_POLL_RD; forever() { if((r = poll_descriptors(2, &pollarg[0], conf.time_out[HTTP]*1000))<=0) { klog(DEBUG_LOG,"poll descriptors is error in file %s line %d\n",__FILE__,__LINE__); goto error; } if(IS_READABLE(&pollarg[1]) || IS_HUPED(&pollarg[1])) { klog(DEBUG_LOG,"prev head value=%d,client close the connection\n",head_status); //head_status=CLIENT_HAVE_DATA; goto error; } if(IS_READABLE(&pollarg[0])) r = rq->client->recv_t(buf,len,0); else { klog(DEBUG_LOG,"unknow error is happen\n"); goto error; } if ( r <= 0 ) { klog(DEBUG_LOG,"recv server data error\n"); goto error; } // buf[r]=0; // printf("%s",buf); buf+=r; len-=r; if ( !(answ_state.state & GOT_HDR) ) { obj->size += r; if ( check_server_headers(&answ_state, obj, answer,r, rq) ) { head_status=HEAD_UNKNOW; rq->flags|=RESULT_CLOSE; // printf("%s:%d\n",__FILE__,__LINE__); goto send_data; } } if ( answ_state.state & GOT_HDR ) { obj->flags|= answ_state.flags; obj->times = answ_state.times; // printf("obj->times.last_modified=%d\n",obj->times.last_modified); if ( !obj->times.date ) obj->times.date = global_sec_timer; // check_new_object_expiration(rq, obj); obj->status_code = answ_state.status_code; if ( obj->status_code != STATUS_OK && obj->status_code!=STATUS_NOT_MODIFIED) { // printf("status is not ok\n"); // printf("obj->status_code=%d.\n",obj->status_code); rq->flags|=RESULT_CLOSE; head_status=HEAD_NOT_OK; goto send_data; } // obj->flags |= FLAG_DEAD; if (TEST(obj->flags , ANSW_NO_STORE) ) { //printf("answer is no cache\n"); head_status=HEAD_OK_NO_STORE; rq->flags|=RESULT_CLOSE; goto send_data; } // obj->flags |= ANSW_NO_CACHE; // downgrade_flags = downgrade(rq, obj); // my_xlog(OOPS_LOG_HTTP|OOPS_LOG_DBG, "fill_mem_obj(): Downgrade flags: %x\n", downgrade_flags); hdrs_to_send = alloc_buff(CHUNK_SIZE); /* most headers fit this (?) */ if ( !hdrs_to_send ) goto error; header = obj->headers; if ( !header ) { rq->flags|=RESULT_CLOSE; goto send_data ; } if ( TEST(obj->flags, ANSW_SHORT_CONTAINER) ) { //printf("answer is short contaner\n"); head_status=HEAD_OK_NO_STORE; rq->flags|=RESULT_CLOSE; goto send_data; } /* first must be "HTTP/1.x 200 ..." */ /* if ( TEST(downgrade_flags, DOWNGRADE_ANSWER) ) { attach_av_pair_to_buff("HTTP/1.0", header->val, hdrs_to_send); header = header->next; } */ while(header) { if(strncasecmp(header->attr,"Set-Cookie:",7)!=0) { //don't cache cookie if(strncasecmp(header->attr,"Connection:",11)==0) { if(!TEST(rq->flags,RQ_HAS_KEEP_CONNECTION)) { attach_av_pair_to_buff("Connection:","close",hdrs_to_send); } else { attach_av_pair_to_buff("Connection:","keep-alive",hdrs_to_send); } goto next_header; } } else { // printf("server has set-cookie\n"); head_status=HEAD_OK_NO_STORE; rq->flags|=RESULT_CLOSE; goto send_data; } attach_av_pair_to_buff(header->attr, header->val, hdrs_to_send); next_header: header = header->next; } attach_av_pair_to_buff("", "", hdrs_to_send); // obj->container=hdrs_to_send; // hdrs_to_send->next=obj->hot_buff; if(obj->status_code==STATUS_NOT_MODIFIED) { head_status=HEAD_NOT_MODIFIED; m_head.head=hdrs_to_send->data; m_head.len=hdrs_to_send->used; hdrs_to_send->data=NULL; // free_container(hdrs_to_send); goto done; } // obj->container=obj->hot_buff; if(rq->server->send(hdrs_to_send->data,hdrs_to_send->used)<0) { // free_container(hdrs_to_send); goto error; } // free_container(hdrs_to_send); // printf("%s\n",hdrs_to_send->data); head_status=HEAD_OK; goto done; } if(len<1) { // printf("head size is too large\n"); head_status=HEAD_UNKNOW; rq->flags|=RESULT_CLOSE; goto send_data;//head size is too large } } error://get head failed obj->flags |= FLAG_DEAD; if(hdrs_to_send) free_container(hdrs_to_send); IF_FREE(answer); return head_status; done://get head ok; if(hdrs_to_send) free_container(hdrs_to_send); free(answer); return head_status; send_data://得到头失败,但要转发数据 if(hdrs_to_send) free_container(hdrs_to_send); m_head.head=answer; m_head.len=ANSW_SIZE-len; answer[m_head.len]=0; return head_status; }
/** * Perform routine maintenance on the resource list. This call * may instantiate new resources or expire old resources. */ static apr_status_t reslist_maint(apr_reslist_t *reslist) { apr_time_t now; apr_status_t rv; apr_res_t *res; int created_one = 0; apr_thread_mutex_lock(reslist->listlock); /* Check if we need to create more resources, and if we are allowed to. */ while (reslist->nidle < reslist->min && reslist->ntotal < reslist->hmax) { /* Create the resource */ rv = create_resource(reslist, &res); if (rv != APR_SUCCESS) { free_container(reslist, res); apr_thread_mutex_unlock(reslist->listlock); return rv; } /* Add it to the list */ push_resource(reslist, res); /* Update our counters */ reslist->ntotal++; /* If someone is waiting on that guy, wake them up. */ rv = apr_thread_cond_signal(reslist->avail); if (rv != APR_SUCCESS) { apr_thread_mutex_unlock(reslist->listlock); return rv; } created_one++; } /* We don't need to see if we're over the max if we were under it before */ if (created_one) { apr_thread_mutex_unlock(reslist->listlock); return APR_SUCCESS; } /* Check if we need to expire old resources */ now = apr_time_now(); while (reslist->nidle > reslist->smax && reslist->nidle > 0) { /* Peak at the last resource in the list */ res = APR_RING_LAST(&reslist->avail_list); /* See if the oldest entry should be expired */ if (now - res->freed < reslist->ttl) { /* If this entry is too young, none of the others * will be ready to be expired either, so we are done. */ break; } APR_RING_REMOVE(res, link); reslist->nidle--; reslist->ntotal--; rv = destroy_resource(reslist, res); free_container(reslist, res); if (rv != APR_SUCCESS) { apr_thread_mutex_unlock(reslist->listlock); return rv; } } apr_thread_mutex_unlock(reslist->listlock); return APR_SUCCESS; }
int ssm_build_container_table() { int i, j, k, ret = 0; ssm_node_t *node; ssm_lun_t *disk; ssm_container_t *container; /* * TODO: Use the minimal size of the disk for now. */ ssm_ctn_col_sz = ssm_resource.sr_min_size; ssm_ctn_ncols = ssm_data_nvecs + ssm_parity_nvecs; ssm_ctn_unit_sz = SSM_CTN_UNIT_SIZE_DEFAULT; /* * Initialize disk block usage map for each disk */ for (i = 0; i < ssm_resource.sr_nnodes; i++) { node = ssm_resource.sr_node[i]; for (j = 0; j < node->sn_ndisks; j++) { disk = node->sn_disks[j]; disk->sl_nblocks = disk->sl_size / ssm_ctn_col_sz; disk->sl_blksz = ssm_ctn_col_sz; disk->sl_blockmap = (unsigned char *) malloc(disk->sl_nblocks * sizeof(unsigned char)); if (!disk->sl_blockmap) { fprintf(stderr, "Failed to allocate memory " "for disk block usage map.\n"); return ENOMEM; } for (k = 0; k < disk->sl_nblocks; k++) { disk->sl_blockmap[k] = SSM_BLOCK_FREE; } } } ssm_print_disk_usage(); while (1) { container = create_container(); if (!container) { break; } ssm_print_container(stdout, ssm_ctn_tbl.scb_entries, container); ssm_print_disk_usage(); if (ssm_ctn_tbl.scb_entries == 0) { ssm_ctn_tbl.scb_ctn = (ssm_container_t **) malloc(sizeof(ssm_container_t *)); } else { ssm_ctn_tbl.scb_ctn = (ssm_container_t **) realloc(ssm_ctn_tbl.scb_ctn, (ssm_ctn_tbl.scb_entries + 1) * sizeof(ssm_container_t *)); } if (!ssm_ctn_tbl.scb_ctn) { fprintf(stderr, "Failed to allocate memory for " "the container table.\n"); free_container(container); ret = ENOMEM; break; } ssm_ctn_tbl.scb_ctn[ssm_ctn_tbl.scb_entries++] = container; } return ret; }
/* * Create a single container * Returns a pointer to container if successfull * Returns NULL if failed */ static ssm_container_t * create_container() { int i, ret; ssm_container_t *container = NULL; /* * Allocate one container */ container = (ssm_container_t *)malloc(sizeof(ssm_container_t)); if (!container) { fprintf(stderr, "Failed to allocate memory for a container.\n"); return NULL; } ret = ssm_guid_create(&container->sc_guid); if (ret != 0 ) { fprintf(stderr, "Failed to generate guid for a container.\n"); free(container); return NULL; } container->sc_genid = 0; container->sc_owner = this_node.sn_hostid; container->sc_colsz = ssm_ctn_col_sz * 1024; container->sc_unitsz = ssm_ctn_unit_sz; container->sc_ncols = ssm_ctn_ncols; container->sc_col = (ssm_column_t *)malloc(container->sc_ncols * sizeof(ssm_column_t)); if (!container->sc_col) { fprintf(stderr, "Failed to allocate memory for columns.\n"); free(container); return NULL; } bzero(container->sc_col, container->sc_ncols * sizeof(ssm_column_t)); /* * Try to allocate the first column from this node */ ret = alloc_column_from_node(&this_node, &container->sc_col[0]); if (ret) { free_container(container); return NULL; } /* * Continue with the rest of the columns */ for (i = 1; i < container->sc_ncols; i++){ ret = alloc_column_from_any(&container->sc_col[i]); if (ret) { free_container(container); return NULL; } } /* * Allocate and initialize the space bitmap */ container->sc_space_bmap = ctn_space_bmap_init(container->sc_colsz, container->sc_unitsz); container->sc_space_avail = container->sc_space_bmap->sb_nbit; return container; }