int
ns_stat_add(ns_stat_token_t	stoken,
            ns_stat_category_t	stat_type,
            int64_t		add_val,
            int64_t		*old_val)
{
    int64_t  tmp_val;
    uint32_t ns_index = stoken.u.stat_token_data.val;
    uint32_t gen = stoken.u.stat_token_data.gen;
    uint32_t curr_gen;

    curr_gen = (uint32_t) AO_load(&ns_token_gen[ns_index]);
    if (curr_gen != gen) {
        glob_ns_stat_add_gen_mismatch_err++;
        return NKN_STAT_GEN_MISMATCH;
    }

    if (stat_type >= NS_STAT_MAX) {
        glob_ns_stat_add_type_einval_err++;
        return NKN_STAT_TYPE_EINVAL;
    }

    tmp_val = AO_fetch_and_add(&ns_stats[ns_index][stat_type], add_val);

    if (old_val)
        *old_val = tmp_val;
    return 0;
}	/* ns_stat_add */
Esempio n. 2
0
static void *
_alloc_proc(void *arg)
{
    int i;
    for (i = 0; i < N_ALLOC; ++i) {
	cu_word_t tpl[1], *obj;
	tpl[0] = (cu_word_t)arg;
	obj = cu_ptr_add(cuoo_halloc(_obj_type, sizeof(cu_word_t), tpl),
			 CUOO_HCOBJ_SHIFT);
	cu_test_assert(*obj == (cu_word_t)arg);
    }
    AO_fetch_and_add(&pending, -1);
    return NULL;
}
Esempio n. 3
0
  DWORD WINAPI entry(LPVOID arg)
#endif
{
    int thread_num = AO_fetch_and_add(&thread_created_cnt, 1);
    GC_word my_depth = (GC_word)arg + 1;

    if (my_depth <= MAX_SUBTHREAD_DEPTH
            && thread_num < MAX_SUBTHREAD_COUNT
            && (thread_num % DECAY_DENOM) < DECAY_NUMER
            && (int)(thread_num - AO_load(&thread_ended_cnt))
                <= MAX_ALIVE_THREAD_COUNT) {
# ifdef GC_PTHREADS
        int err;
        pthread_t th;
        err = pthread_create(&th, NULL, entry, (void *)my_depth);
        if (err) {
            fprintf(stderr, "Thread #%d creation failed: %s", thread_num,
                    strerror(err));
            exit(2);
        }
# else
        HANDLE th;
        DWORD thread_id;
        th = CreateThread(NULL, 0, entry, (LPVOID)my_depth, 0, &thread_id);
        if (th == NULL) {
            printf("Thread #%d creation failed: %d\n", thread_num,
                   (int)GetLastError());
            exit(2);
        }
        CloseHandle(th);
# endif
    }

    AO_fetch_and_add(&thread_ended_cnt, 1);
    return 0;
}
/*
 *******************************************************************************
 * Internal functions
 *******************************************************************************
 */
static void *
int_nkn_memalloc_malloc(size_t size,
			size_t align,
			nkn_obj_type_t type)
{
    size_t alloc_size;
    void *ptr;
    char *data;
    mem_alloc_hdr_t *mh;
    mem_slot_queue_t *pslot = NULL;
    int align_log2;
    int n;
    int ispool = MEM_SLOT_GLIB;

    if (size >= MH_MAX_MEMORY_SIZE || type >= MH_MAX_TYPE_VAL) {
	assert(0);
    }

    if (align) {
	// Note: align is assumed to be a pwr2 and multiple of sizeof(void*)
	for (n = 1; (n * align) < sizeof(mem_alloc_hdr_t); n++)
            ;
    } else {
	n = 0;
    }

    alloc_size = ALLOC_SIZE(size, (n * align));
    if (align) {
        // compute log2(align)
        for (align_log2 = CHUNK_SIZE_LOG2;
	     align > (size_t)(1 << align_log2); align_log2++)
	    ;
        ptr = __libc_memalign(align, alloc_size);
    } else {
        align_log2 = 0;
	ptr = mem_get_memory(0, &alloc_size, &ispool, &pslot);	// alloc_size may be
						// modified
    }
    if (ptr) {
	data = (char *)ptr + (align ? (n * align) : sizeof(mem_alloc_hdr_t));
	mh = (mem_alloc_hdr_t *)(data - sizeof(mem_alloc_hdr_t));
	mh->magicno = MH_MAGIC;
	mh->type = type;
	mh->size_chunk_units = (size_t)(alloc_size >> CHUNK_SIZE_LOG2);
	if (align_log2 >= MH_MAX_ALIGN_VAL)
	    assert(0);
	mh->align_log2 = align_log2;
	mh->align_units = n;
	mh->flags = ispool;
	mh->pslot = pslot;

	// Update stats
	if (type < nkn_malloc_max_mem_types) {
	    AO_fetch_and_add(obj_type_data[type].cnt, alloc_size);
	    *obj_type_data[type].obj_size = alloc_size;
	    if (ispool)
		AO_fetch_and_add1(obj_type_data[type].nlib);
	    else {
		AO_fetch_and_add1(obj_type_data[type].glib);
	    }
	}

	return MHDR_TO_MEM(mh);
    } else {
	return 0;
static int vcs_fuse_slot_read(
    nkn_vc_channel_t *ch,
    vccmp_slot_read_address_t addr,
    const char *path,
    char *buf,
    size_t size,
    off_t offset)
{
    uint32_t slot_index = (uint32_t)(addr.fields.index);
    off_t read_offset = (off_t)(addr.fields.offset);
    uint8_t nonce = (uint8_t)(addr.fields.nonce);
    nkn_vc_slot_t *slot = NULL;
    size_t length, extra = 0;
    int rc = 0;

    if (slot_index >= VCCMP_SLOTS_PER_CHANNEL) {
	DBG_VCE("(READ) invalid slot index: %u\n", slot_index);
	/* FUSE likely prevents this from happening via filesize. */
	return -EINVAL;
    }

    slot = vcs_slot_get(ch, slot_index, nonce);

    if (slot != NULL) {
	length = size;
	if (read_offset + length > slot->file_length) {
	    extra = (read_offset + length) - slot->file_length;
	    if (extra <= length) {
		length -= extra;
	    } else {
		length = 0;
		extra = size;
	    }
	}
    } else {
	length = 0;
	extra = size;
    }

    if (length > 0) {
	uint8_t direct = 0;
	size_t srs = (size_t)slot->streaming_read_size;
	if (srs && (length != srs) && (read_offset + length < slot->file_length))
	    direct = 1;
	rc = vfs_funs.pnkn_vcread(slot->vfp, buf, length, read_offset, direct,
				  slot->streaming_read_size);
	if (rc < 0) {
	    DBG_VCE("(READ) pnkn_vcread(%s) failed: %s\n", slot->uri, strerror(errno));
	    vcs_slot_put(ch, slot, slot_index);
	    AO_fetch_and_add1(&vc->total_read_errors_cnt);
	    AO_fetch_and_add1(&ch->total_read_errors_cnt);
	    return -errno;
	}
	AO_fetch_and_add(&vc->total_bytes_read_cnt, length);
	AO_fetch_and_add(&ch->total_bytes_read_cnt, length);
	buf += length;
    }

    if (extra > 0) {
	memset(buf, 0, extra);
    }

    DBG_VCM("READ[SLOT] %s\n"
	     "  %s\n"
	     "  slot index:   %u\n"
	     "  close flag:   %ld\n"
	     "  size:         %u\n"
	     "  offset:       %"PRIu64"\n"
	     "  read offset:  %"PRIu64"\n"
	     "  extra:        %u\n",
	     path, 
	     (slot != NULL) ? slot->uri : "<empty slot>",
	     slot_index,
	     (slot != NULL) ? AO_load(&slot->close_flag) : 0,
	     (uint32_t)size, 
	     (uint64_t)offset, 
	     (uint64_t)read_offset, 
	     (uint32_t)extra);

    vcs_slot_put(ch, slot, slot_index);

    return size;
}
int http_build_res_common(http_cb_t * phttp, int status_code, int errcode, mime_header_t * presponse_hdr)
{
	int rv;
	mime_header_t response_hdr;
	int presponse_hdr_from;
	const namespace_config_t *nsconf = phttp->nsconf;
	const char *cookie_str;
	int cookie_len, rv1;
	u_int32_t attrs;
	int hdrcnt, nth;

	/*
	 * response header has already been built.
	 */
	if(phttp->res_hdlen || CHECK_HTTP_FLAG(phttp, HRF_RES_HEADER_SENT))
		return 1;

	// For HTTP 0.9 requests do not generate response headers.
	if (CHECK_HTTP_FLAG(phttp, HRF_HTTP_09)) return 1;

	/* 
	 * case 1: presponse_hdr presents. e.g. tunnel code path calls for build_up_response.
	 * case 2: phttp->attr presents. e.g. cache hit code path calls for build_up_response.
	 * case 3: Both are NULL or !errcode. e.g. HTTP request parser error.
	 */
	if(presponse_hdr && !errcode) {
		// case 1
		presponse_hdr_from = 1;
	}
	else if(phttp->attr && !errcode) {
		// case 2
		presponse_hdr_from = 2;
		init_http_header(&response_hdr, 0, 0);
	        rv = nkn_attr2http_header(phttp->attr, 1, &response_hdr);
		if (rv) {
			DBG_LOG(MSG, MOD_HTTP, "nkn_attr2http_header() failed,  rv=%d", rv);
			return 1;
		}
		presponse_hdr = &response_hdr;

		if(CHECK_HTTP_FLAG(phttp, HRF_SSP_CONFIGURED)) {
		    if ( phttp->p_ssp_cb->ssp_client_id == 6 ) {
			switch (phttp->p_ssp_cb->ssp_streamtype) {
			    case NKN_SSP_SMOOTHSTREAM_STREAMTYPE_MANIFEST:
				add_known_header(presponse_hdr, MIME_HDR_CONTENT_TYPE, "text/xml", 8);
				break;
			    case NKN_SSP_SMOOTHSTREAM_STREAMTYPE_VIDEO:
				add_known_header(presponse_hdr, MIME_HDR_CONTENT_TYPE, "video/mp4", 9);
                                break;
			    case NKN_SSP_SMOOTHSTREAM_STREAMTYPE_AUDIO:
				add_known_header(presponse_hdr, MIME_HDR_CONTENT_TYPE, "audio/mp4", 9);
                                break;
			}
		    } else if ( phttp->p_ssp_cb->ssp_client_id == 7 ) {
			switch (phttp->p_ssp_cb->ssp_streamtype) {
			    case NKN_SSP_FLASHSTREAM_STREAMTYPE_FRAGMENT:
				add_known_header(presponse_hdr, MIME_HDR_CONTENT_TYPE, "video/f4f", 9);
                                break;
			}
		    }
		}

		/* Special case for cookie handling. If set cookie cacheable, then we've to append
		 * the respective cookie headers back to the client response. This is done here 
		 * because under such scenarios we would've stripped the cookie header from the 
		 * origin reponse before caching the object.
		 */
		if (CHECK_HTTP_FLAG(phttp, HRF_CACHE_COOKIE)) {
			if (is_known_header_present(&phttp->hdr, MIME_HDR_SET_COOKIE)) {
				mime_hdr_get_known(&phttp->hdr, MIME_HDR_SET_COOKIE, 
						&cookie_str, &cookie_len, &attrs, &hdrcnt);
				for(nth = 0; nth < hdrcnt; nth++) {
					rv1 = get_nth_known_header(&phttp->hdr, MIME_HDR_SET_COOKIE, 
								nth, &cookie_str, &cookie_len, &attrs);
					if (!rv1) {
						add_known_header(presponse_hdr, MIME_HDR_SET_COOKIE, 
								cookie_str, cookie_len);
					} else {
						DBG_LOG(MSG, MOD_OM,
							"add_known_header() failed rv=%d nth=%d, MIME_HDR_SET_COOKIE ",
							rv1, nth);
					}
				}
			} 

			if (is_known_header_present(&phttp->hdr, MIME_HDR_SET_COOKIE2)) {
				mime_hdr_get_known(&phttp->hdr, MIME_HDR_SET_COOKIE2, 
						&cookie_str, &cookie_len, &attrs, &hdrcnt);
				for(nth = 0; nth < hdrcnt; nth++) {
					rv1 = get_nth_known_header(&phttp->hdr, MIME_HDR_SET_COOKIE2, 
								nth, &cookie_str, &cookie_len, &attrs);
					if (!rv1) {
						add_known_header(presponse_hdr, MIME_HDR_SET_COOKIE2, 
								cookie_str, cookie_len);
					} else {
						DBG_LOG(MSG, MOD_OM,
							"add_known_header() failed rv=%d nth=%d, MIME_HDR_SET_COOKIE2 ",
							rv1, nth);
					}
				}
			}
		}
	}
	else {
		// case 3
		presponse_hdr_from = 3;
		init_http_header(&response_hdr, 0, 0);
		presponse_hdr = &response_hdr;
		if(CHECK_HTTP_FLAG(phttp, HRF_SSP_SF_RESPONSE)) {
			char buf[100];
			snprintf(buf, 100, "%d", sizeof_response_200_OK_body);
			add_known_header(presponse_hdr, MIME_HDR_CONTENT_LENGTH, buf, strlen(buf));
		}
	}

	/*
	 * build up the response header, output is saved in
	 * phttp->resp_buf, length is phttp->res_hdlen;
	 */
	phttp->respcode = status_code;
	if (errcode) {
		phttp->subcode = errcode;
	}

	/*
	 * Counter update.
	 */
	switch(status_code) {
		case 100: 
			setup_http_build_100(phttp, presponse_hdr);
			break;
		case 200: 
			setup_http_build_200(phttp, presponse_hdr);
			break;
		case 206: 
			setup_http_build_206(phttp, presponse_hdr);
			break;
		case 304: 
			setup_http_build_304(phttp, presponse_hdr);
			break;
		case 302: 
		case 400:
		case 403:
		case 404:
		case 405:
		case 413:
		case 414:
		case 416:
		case 417:
			setup_http_build_others(phttp, presponse_hdr);
			break;
		case 500:
		case 501:
		case 503:

			/* Requirement 2.1 - 34. 
			 * If retry-after is enabled, set the header in the
			 * response message.
			 */
			if ((phttp->nsconf != NULL) && 
				(errcode == NKN_HTTP_NS_MAX_CONNS) &&
				(phttp->nsconf->http_config->retry_after_time > 0)) {
				char buf[100];
				snprintf(buf, 100, "%d", phttp->nsconf->http_config->retry_after_time);
				add_known_header(presponse_hdr, MIME_HDR_RETRY_AFTER, buf, strlen(buf));
			}

		case 502:
		case 504:
		default:
			CLEAR_HTTP_FLAG(phttp, HRF_CONNECTION_KEEP_ALIVE);
			setup_http_build_others(phttp, presponse_hdr);
			break;
	}

	/* Add Via header and date headers before PE is called
	 */
	http_add_via_and_date_header(phttp, presponse_hdr);

	/* Apply Policy for http send response here
	 */
	if (nsconf && nsconf->http_config && nsconf->http_config->policy_engine_config.policy_file) {
		pe_ilist_t * p_list = NULL;
		pe_rules_t * p_perule;

		p_perule = pe_create_rule(&nsconf->http_config->policy_engine_config, &p_list);
		if (p_perule) {
			uint64_t action;
			action = pe_eval_http_send_response(p_perule, phttp, presponse_hdr);
			pe_free_rule(p_perule, p_list);
		}
	}

	http_buildup_resp_header(phttp, presponse_hdr);

	/*   
	 * accesslog format could configure to record response header.   
	 * Because sizeof(mime_header_t) is too big,   
	 * we better not add response header into phttp structure which will waste too much memory.   
	 * It is not needed for R-Proxy case. 
	 */
	if (phttp->nsconf && phttp->nsconf->acclog_config->al_resp_header_configured) {
		if (phttp->p_resp_hdr) {
			shutdown_http_header(phttp->p_resp_hdr);
			free(phttp->p_resp_hdr);
		}
		phttp->p_resp_hdr = (mime_header_t *)nkn_malloc_type(sizeof(mime_header_t),
							    mod_http_mime_header_t);
		if (phttp->p_resp_hdr) {
			init_http_header(phttp->p_resp_hdr, 0, 0);
			copy_http_headers(phttp->p_resp_hdr, presponse_hdr);   
		}
	}

	if (presponse_hdr_from != 1) {
		shutdown_http_header(&response_hdr);
	}

	/*
	 * Update counters with header size.
	 */
	if ( (status_code != 304) && 
	     !CHECK_HTTP_FLAG(phttp, HRF_METHOD_HEAD) &&
	     !CHECK_HTTP_FLAG(phttp, HRF_MFC_PROBE_REQ) ) {
	switch(phttp->provider){
	case BufferCache_provider:
		AO_fetch_and_add(&glob_tot_size_from_cache, phttp->res_hdlen);
		break;

	case SASDiskMgr_provider:
	case SAS2DiskMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_sas_disk, phttp->res_hdlen);
		AO_fetch_and_add(&glob_tot_size_from_disk, phttp->res_hdlen);
		break;
	case SATADiskMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_sata_disk, phttp->res_hdlen);
		AO_fetch_and_add(&glob_tot_size_from_disk, phttp->res_hdlen);
		break;
	case SolidStateMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_ssd_disk, phttp->res_hdlen);
		AO_fetch_and_add(&glob_tot_size_from_disk, phttp->res_hdlen);
		break;
	case NFSMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_nfs, phttp->res_hdlen);
		break;
	case TFMMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_tfm, phttp->res_hdlen);
		break;
	case OriginMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_origin, phttp->res_hdlen);
		break;
	case Tunnel_provider:
		// Will be added in the fp_forward_server_to_client().
	default:
		break;
	}

	}

    if (304 == status_code)
    {
	switch(phttp->provider){
	case BufferCache_provider:
		AO_fetch_and_add(&glob_tot_size_from_cache, -(phttp->tot_reslen));
		break;

	case SASDiskMgr_provider:
	case SAS2DiskMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_sas_disk, -(phttp->tot_reslen));
		AO_fetch_and_add(&glob_tot_size_from_disk, -(phttp->tot_reslen));
		break;
	case SATADiskMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_sata_disk, -(phttp->tot_reslen));
		AO_fetch_and_add(&glob_tot_size_from_disk, -(phttp->tot_reslen));
		break;
	case SolidStateMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_ssd_disk, -(phttp->tot_reslen));
		AO_fetch_and_add(&glob_tot_size_from_disk, -(phttp->tot_reslen));
		break;
	case NFSMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_nfs, -(phttp->tot_reslen));
		break;
	case TFMMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_tfm, -(phttp->tot_reslen));
		break;
	case OriginMgr_provider:
		AO_fetch_and_add(&glob_tot_size_from_origin, -(phttp->tot_reslen));
		break;
	case Tunnel_provider:
		// Will be added in the fp_forward_server_to_client().
	default:
		break;
	}

	}

	return 1;
}