亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? erl_async.c

?? OTP是開放電信平臺的簡稱
?? C
字號:
/*** Asyncronous*/#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "sys.h"#include "erl_sys_driver.h"#include "global.h"#include "erl_threads.h"typedef struct _erl_async {    struct _erl_async* next;    struct _erl_async* prev;    DE_Handle*         hndl;   /* The DE_Handle is needed when port is gone */    Eterm              port;    long               async_id;    void*              async_data;    ErlDrvPDL          pdl;    void (*async_invoke)(void*);    void (*async_free)(void*);} ErlAsync;typedef struct {    erts_mtx_t mtx;    erts_cnd_t cv;    erts_tid_t thr;    int   len;#ifndef ERTS_SMP    int   hndl;#endif    ErlAsync* head;    ErlAsync* tail;#ifdef ERTS_ENABLE_LOCK_CHECK    int no;#endif} AsyncQueue;static erts_smp_spinlock_t async_id_lock;static long async_id = 0;#ifndef ERTS_SMPerts_mtx_t async_ready_mtx;static ErlAsync* async_ready_list = NULL;#endif/*** Initialize worker threads (if supported)*//* Detach from driver */static void async_detach(DE_Handle* dh){    /* XXX:PaN what should happen here? we want to unload the driver or??? */    return;}#ifdef USE_THREADSstatic AsyncQueue* async_q;static void* async_main(void*);static void async_add(ErlAsync*, AsyncQueue*);int init_async(int hndl){    erts_thr_opts_t thr_opts = ERTS_THR_OPTS_DEFAULT_INITER;    AsyncQueue* q;    int i;    thr_opts.detached = 0;    thr_opts.suggested_stack_size = erts_async_thread_suggested_stack_size;#ifndef ERTS_SMP    erts_mtx_init(&async_ready_mtx, "async_ready");    async_ready_list = NULL;#endif    async_id = 0;    erts_smp_spinlock_init(&async_id_lock, "async_id");    async_q = q = (AsyncQueue*)	(erts_async_max_threads	 ? erts_alloc(ERTS_ALC_T_ASYNC_Q,		      erts_async_max_threads * sizeof(AsyncQueue))	 : NULL);    for (i = 0; i < erts_async_max_threads; i++) {	q->head = NULL;	q->tail = NULL;	q->len = 0;#ifndef ERTS_SMP	q->hndl = hndl;#endif#ifdef ERTS_ENABLE_LOCK_CHECK	q->no = i;#endif	erts_mtx_init(&q->mtx, "asyncq");	erts_cnd_init(&q->cv);	erts_thr_create(&q->thr, async_main, (void*)q, &thr_opts);	q++;    }    return 0;}int exit_async(){    int i;    /* terminate threads */    for (i = 0; i < erts_async_max_threads; i++) {	ErlAsync* a = (ErlAsync*) erts_alloc(ERTS_ALC_T_ASYNC,					     sizeof(ErlAsync));	a->port = NIL;	async_add(a, &async_q[i]);    }    for (i = 0; i < erts_async_max_threads; i++) {	erts_thr_join(async_q[i].thr, NULL);	erts_mtx_destroy(&async_q[i].mtx);	erts_cnd_destroy(&async_q[i].cv);    }#ifndef ERTS_SMP    erts_mtx_destroy(&async_ready_mtx);#endif    if (async_q)	erts_free(ERTS_ALC_T_ASYNC_Q, (void *) async_q);    return 0;}static void async_add(ErlAsync* a, AsyncQueue* q){    /* XXX:PaN Is this still necessary when ports lock drivers? */    if (is_internal_port(a->port)) {	ERTS_LC_ASSERT(erts_drvportid2port(a->port));	/* make sure the driver will stay around */	driver_lock_driver(internal_port_index(a->port));    }    erts_mtx_lock(&q->mtx);    if (q->len == 0) {	q->head = a;	q->tail = a;	q->len = 1;	erts_cnd_signal(&q->cv);    }    else { /* no need to signal (since the worker is working) */	a->next = q->head;	q->head->prev = a;	q->head = a;	q->len++;    }    erts_mtx_unlock(&q->mtx);}static voidprepare_for_block(void *vmtxp){    erts_mtx_unlock((erts_mtx_t *) vmtxp);}static voidresume_after_block(void *vmtxp){    erts_mtx_lock((erts_mtx_t *) vmtxp);}static ErlAsync* async_get(AsyncQueue* q){    ErlAsync* a;    erts_mtx_lock(&q->mtx);    erts_smp_activity_change(ERTS_ACTIVITY_IO,			     ERTS_ACTIVITY_WAIT,			     prepare_for_block,			     resume_after_block,			     (void *) &q->mtx);    while((a = q->tail) == NULL) {	erts_cnd_wait(&q->cv, &q->mtx);    }    erts_smp_activity_change(ERTS_ACTIVITY_WAIT,			     ERTS_ACTIVITY_IO,			     prepare_for_block,			     resume_after_block,			     (void *) &q->mtx);#ifdef ERTS_SMP    ASSERT(a && q->tail == a);#endif    if (q->head == q->tail) {	q->head = q->tail = NULL;	q->len = 0;    }    else {	q->tail->prev->next = NULL;	q->tail = q->tail->prev;	q->len--;    }    erts_mtx_unlock(&q->mtx);    return a;}static int async_del(long id){    int i;    /* scan all queue for an entry with async_id == 'id' */    for (i = 0; i < erts_async_max_threads; i++) {	ErlAsync* a;	erts_mtx_lock(&async_q[i].mtx);		a = async_q[i].head;	while(a != NULL) {	    if (a->async_id == id) {		if (a->prev != NULL)		    a->prev->next = a->next;		else		    async_q[i].head = a->next;		if (a->next != NULL)		    a->next->prev = a->prev;		else		    async_q[i].tail = a->prev;		async_q[i].len--;		erts_mtx_unlock(&async_q[i].mtx);		if (a->async_free != NULL)		    a->async_free(a->async_data);		async_detach(a->hndl);		erts_free(ERTS_ALC_T_ASYNC, a);		return 1;	    }	}	erts_mtx_unlock(&async_q[i].mtx);    }    return 0;}static void* async_main(void* arg){    AsyncQueue* q = (AsyncQueue*) arg;#ifdef ERTS_ENABLE_LOCK_CHECK    {	char buf[27];	erts_snprintf(&buf[0], 27, "async %d", q->no);	erts_lc_set_thread_name(&buf[0]);    }#endif#ifdef ERTS_SMP    erts_register_blockable_thread();#endif    erts_smp_activity_begin(ERTS_ACTIVITY_IO, NULL, NULL, NULL);    while(1) {	ErlAsync* a = async_get(q);	if (a->port == NIL) { /* TIME TO DIE SIGNAL */	    erts_free(ERTS_ALC_T_ASYNC, (void *) a);	    break;	}	else {	    (*a->async_invoke)(a->async_data);	    /* Major problem if the code for async_invoke	       or async_free is removed during a blocking operation */#ifdef ERTS_SMP	    {		Port *p;		p = erts_id2port_sflgs(a->port,				       NULL,				       0,				       ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP);		if (p) {		    if (async_ready(p, a->async_data)) {			if (a->async_free)			    (*a->async_free)(a->async_data);		    }		    async_detach(a->hndl);		    erts_port_release(p);		}		if (a->pdl) {		    driver_pdl_dec_refc(a->pdl);		}		erts_free(ERTS_ALC_T_ASYNC, (void *) a);	    }#else	    if (a->pdl) {		driver_pdl_dec_refc(a->pdl);	    }	    erts_mtx_lock(&async_ready_mtx);	    a->next = async_ready_list;	    async_ready_list = a;	    erts_mtx_unlock(&async_ready_mtx);	    sys_async_ready(q->hndl);#endif	}    }    erts_smp_activity_end(ERTS_ACTIVITY_IO, NULL, NULL, NULL);    return NULL;}#endif#ifndef ERTS_SMPint check_async_ready(){    ErlAsync* a;    int count = 0;    erts_mtx_lock(&async_ready_mtx);    a = async_ready_list;    async_ready_list = NULL;    erts_mtx_unlock(&async_ready_mtx);    while(a != NULL) {	ErlAsync* a_next = a->next;	/* Every port not dead */	Port *p = erts_id2port_sflgs(a->port,				     NULL,				     0,				     ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP);	if (p != NULL) {	    count++;	    if (async_ready(p, a->async_data)) {		if (a->async_free != NULL)		    (*a->async_free)(a->async_data);	    }	    async_detach(a->hndl);	    erts_port_release(p);	}	erts_free(ERTS_ALC_T_ASYNC, (void *) a);	a = a_next;    }    return count;}#endif/*** Schedule async_invoke on a worker thread** NOTE will be syncrounous when threads are unsupported** return values:**  0  completed **  -1 error**  N  handle value (used with async_cancel)**  arguments:**      ix             driver index **      key            pointer to secedule queue (NULL means round robin)**      async_invoke   function to run in thread**      async_data     data to pass to invoke function**      async_free     function for relase async_data in case of failure*/long driver_async(ErlDrvPort ix, unsigned int* key,		  void (*async_invoke)(void*), void* async_data,		  void (*async_free)(void*)){    ErlAsync* a = (ErlAsync*) erts_alloc(ERTS_ALC_T_ASYNC, sizeof(ErlAsync));    Port* prt = erts_drvport2port(ix);    long id;    unsigned int qix;    if (!prt)	return -1;    ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));    a->next = NULL;    a->prev = NULL;    a->hndl = (DE_Handle*)prt->drv_ptr->handle;    a->port = prt->id;    a->pdl = NULL;    a->async_data = async_data;    a->async_invoke = async_invoke;    a->async_free = async_free;    erts_smp_spin_lock(&async_id_lock);    async_id = (async_id + 1) & 0x7fffffff;    if (async_id == 0)	async_id++;    id = async_id;    erts_smp_spin_unlock(&async_id_lock);    a->async_id = id;    if (key == NULL) {	qix = (erts_async_max_threads > 0)	    ? (id % erts_async_max_threads) : 0;    }    else {	qix = (erts_async_max_threads > 0) ? 	    (*key % erts_async_max_threads) : 0;	*key = qix;    }#ifdef USE_THREADS    if (erts_async_max_threads > 0) {	if (prt->port_data_lock) {	    driver_pdl_inc_refc(prt->port_data_lock);	    a->pdl = prt->port_data_lock;	}	async_add(a, &async_q[qix]);	return id;    }#endif    (*a->async_invoke)(a->async_data);    if (async_ready(prt, a->async_data)) {	if (a->async_free != NULL)	    (*a->async_free)(a->async_data);    }    erts_free(ERTS_ALC_T_ASYNC, (void *) a);    return id;}int driver_async_cancel(unsigned int id){#ifdef USE_THREADS    if (erts_async_max_threads > 0)	return async_del(id);#endif    return 0;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品天美传媒| 国产精品毛片大码女人| 欧美激情综合在线| 亚洲国产精品天堂| 99久久综合国产精品| 日韩欧美综合一区| 亚洲午夜免费电影| av激情综合网| 国产精品全国免费观看高清 | 亚洲视频在线一区| 青青青爽久久午夜综合久久午夜| www.色精品| 日本一区二区三区电影| 久久机这里只有精品| 欧美日韩mp4| 樱桃视频在线观看一区| 成人av动漫在线| 2021国产精品久久精品| 免费在线观看日韩欧美| 精品久久久久久久久久久院品网| 亚洲视频免费观看| 久久精品亚洲一区二区三区浴池 | 国产精品一区二区在线看| 欧美性大战久久久| 中文字幕一区av| 国产黄色91视频| 欧美mv和日韩mv的网站| 午夜久久久影院| 欧美日产在线观看| 婷婷综合久久一区二区三区| 欧美日韩在线三区| 亚洲大尺度视频在线观看| 欧美色图免费看| 香蕉av福利精品导航| 欧美精品第一页| 免费观看日韩av| 日韩视频免费直播| 国产在线播精品第三| 国产欧美日韩综合精品一区二区| 韩国午夜理伦三级不卡影院| 欧美成人a在线| 国精产品一区一区三区mba视频| 日韩片之四级片| 国产成人精品免费在线| 中文字幕在线不卡国产视频| 99视频热这里只有精品免费| 亚洲激情成人在线| 欧美性猛片xxxx免费看久爱| 亚洲成年人网站在线观看| 欧美高清激情brazzers| 免费在线观看成人| 国产日韩欧美高清在线| 91啪九色porn原创视频在线观看| 亚洲欧美另类小说视频| 欧美美女激情18p| 激情欧美一区二区| 国产精品久久福利| 欧美三级在线看| 欧洲精品一区二区三区在线观看| 亚洲小少妇裸体bbw| 日韩免费观看高清完整版| 国产成人精品亚洲777人妖 | eeuss鲁片一区二区三区| 亚洲男人天堂一区| 欧美一卡二卡在线观看| 国产毛片精品一区| 亚洲一区二区精品视频| 久久久精品免费网站| 一本到不卡免费一区二区| 日本亚洲一区二区| 国产精品国产三级国产aⅴ入口| 欧美日韩免费高清一区色橹橹 | 成人看片黄a免费看在线| 一区二区视频在线看| 欧美草草影院在线视频| av在线播放一区二区三区| 免费av成人在线| 亚洲美女一区二区三区| 精品久久久久久久久久久院品网 | 国产精品资源在线观看| 一级精品视频在线观看宜春院| 欧美浪妇xxxx高跟鞋交| proumb性欧美在线观看| 日本女优在线视频一区二区| 一区在线播放视频| 精品剧情v国产在线观看在线| 色欧美88888久久久久久影院| 久久国产精品99久久久久久老狼| 亚洲三级电影网站| 国产婷婷色一区二区三区在线| 欧美色视频在线观看| eeuss鲁片一区二区三区在线观看| 精品制服美女久久| 天堂精品中文字幕在线| 日韩毛片在线免费观看| 国产欧美日韩综合精品一区二区| 日韩女优制服丝袜电影| 91精品国产色综合久久不卡蜜臀 | 1000部国产精品成人观看| 精品久久久久久久久久久院品网 | 久久久久久9999| 欧美一级淫片007| 欧美日韩一二区| 欧美视频中文字幕| 91成人免费电影| 91浏览器入口在线观看| eeuss影院一区二区三区| 成人免费高清视频| 成人性生交大片免费| 成人激情免费网站| 成人免费视频app| 成人网男人的天堂| 99久久久精品| 91在线观看一区二区| 99精品热视频| 一本大道综合伊人精品热热| 在线看日本不卡| 欧美在线观看一区二区| 欧美色综合网站| 欧美揉bbbbb揉bbbbb| 欧美精品三级在线观看| 欧美一区二区精品久久911| 欧美一区午夜视频在线观看| 欧美一级黄色片| 26uuu国产在线精品一区二区| wwwwxxxxx欧美| 久久精品视频一区二区| 国产精品视频一二三区| 自拍偷拍欧美激情| 玉米视频成人免费看| 亚洲成人av电影在线| 毛片av中文字幕一区二区| 国产一区二区三区黄视频 | 中文乱码免费一区二区| 日韩毛片精品高清免费| 亚洲一区视频在线观看视频| 日韩av在线播放中文字幕| 久久99国产精品麻豆| 成人精品gif动图一区| 欧美专区日韩专区| 欧美va亚洲va在线观看蝴蝶网| 久久精品欧美日韩| 亚洲无线码一区二区三区| 久久精品72免费观看| 成人国产一区二区三区精品| 欧美在线一二三四区| 日韩三级高清在线| 亚洲视频图片小说| 奇米精品一区二区三区在线观看 | 日本成人在线一区| 国产精品一区二区久久精品爱涩| proumb性欧美在线观看| 日韩一区二区三区电影在线观看| 欧美国产亚洲另类动漫| 亚洲成av人片一区二区三区| 精品一区二区精品| 在线观看www91| 国产夜色精品一区二区av| 亚洲福利国产精品| 成年人国产精品| 欧美一级欧美三级在线观看| 中文字幕在线观看一区| 毛片av一区二区| 在线视频欧美区| 欧美国产欧美综合| 日本欧美一区二区三区| 97精品国产97久久久久久久久久久久| 日韩一区二区三区视频| 有码一区二区三区| 成人午夜视频在线观看| 日韩精品最新网址| 亚洲成人精品一区二区| 色悠久久久久综合欧美99| 国产欧美一区二区三区鸳鸯浴 | 国产成人午夜精品影院观看视频 | 欧美激情中文不卡| 精品亚洲国内自在自线福利| 欧美三级电影网| 亚洲男人的天堂av| 国产成人日日夜夜| 欧美变态tickling挠脚心| 亚洲成av人综合在线观看| 91精彩视频在线观看| 欧美激情资源网| 国产91精品在线观看| 久久嫩草精品久久久精品| 日本美女一区二区| 欧美日本在线播放| 亚洲一区二区影院| 欧美亚洲动漫精品| 一区二区三区91| 色天天综合色天天久久| 亚洲精选在线视频| 色综合天天综合狠狠| 综合久久一区二区三区| 99r精品视频| 亚洲欧美影音先锋| 99久久国产综合精品女不卡| 国产精品美女久久久久久| 成人国产免费视频|