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

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

?? usage.c

?? 一個開源的sip源代碼
?? C
字號:
/* $Id: usage.c 1266 2007-05-11 15:14:34Z bennylp $ */
/* 
 * Copyright (C) 2003-2005 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "server.h"

struct worker
{
    pj_ioqueue_op_key_t	read_key;
    unsigned		index;
    pj_uint8_t		readbuf[4000];
    pj_sockaddr		src_addr;
    int			src_addr_len;
};

struct pj_stun_usage
{
    pj_pool_t		*pool;
    pj_stun_server	*srv;
    pj_mutex_t		*mutex;
    pj_stun_usage_cb	 cb;
    int			 type;
    pj_sock_t		 sock;
    pj_ioqueue_key_t	*key;
    unsigned		 worker_cnt;
    struct worker	*worker;

    pj_ioqueue_op_key_t	*send_key;
    unsigned		 send_count, send_index;

    pj_bool_t		 quitting;
    void		*user_data;
};


static void on_read_complete(pj_ioqueue_key_t *key, 
                             pj_ioqueue_op_key_t *op_key, 
                             pj_ssize_t bytes_read);

/*
 * Create STUN usage.
 */
PJ_DEF(pj_status_t) pj_stun_usage_create( pj_stun_server *srv,
					  const char *name,
					  const pj_stun_usage_cb *cb,
					  int family,
					  int type,
					  int protocol,
					  const pj_sockaddr_t *local_addr,
					  int addr_len,
					  pj_stun_usage **p_usage)
{
    pj_stun_server_info *si;
    pj_pool_t *pool;
    pj_stun_usage *usage;
    pj_ioqueue_callback ioqueue_cb;
    unsigned i;
    pj_status_t status;

    si = pj_stun_server_get_info(srv);

    pool = pj_pool_create(si->pf, name, 4000, 4000, NULL);
    usage = PJ_POOL_ZALLOC_T(pool, pj_stun_usage);
    usage->pool = pool;
    usage->srv = srv;

    status = pj_mutex_create_simple(pool, name, &usage->mutex);
    if (status != PJ_SUCCESS)
	goto on_error;

    usage->type = type;
    status = pj_sock_socket(family, type, protocol, &usage->sock);
    if (status != PJ_SUCCESS)
	goto on_error;

    status = pj_sock_bind(usage->sock, local_addr, addr_len);
    if (status != PJ_SUCCESS)
	goto on_error;

    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb));
    ioqueue_cb.on_read_complete = &on_read_complete;
    status = pj_ioqueue_register_sock(usage->pool, si->ioqueue, usage->sock,
				      usage, &ioqueue_cb, &usage->key);
    if (status != PJ_SUCCESS)
	goto on_error;

    usage->worker_cnt = si->thread_cnt;
    usage->worker = (struct worker*) pj_pool_calloc(pool, si->thread_cnt, 
				   		    sizeof(struct worker));
    for (i=0; i<si->thread_cnt; ++i) {
	pj_ioqueue_op_key_init(&usage->worker[i].read_key, 
			       sizeof(usage->worker[i].read_key));
	usage->worker[i].index = i;
    }

    usage->send_count = usage->worker_cnt * 2;
    usage->send_key = (pj_ioqueue_op_key_t*)
		      pj_pool_calloc(pool, usage->send_count, 
				     sizeof(pj_ioqueue_op_key_t));
    for (i=0; i<usage->send_count; ++i) {
	pj_ioqueue_op_key_init(&usage->send_key[i], 
			       sizeof(usage->send_key[i]));
    }

    for (i=0; i<si->thread_cnt; ++i) {
	pj_ssize_t size;

	size = sizeof(usage->worker[i].readbuf);
	usage->worker[i].src_addr_len = sizeof(usage->worker[i].src_addr);
	status = pj_ioqueue_recvfrom(usage->key, &usage->worker[i].read_key,
				     usage->worker[i].readbuf, &size, 
				     PJ_IOQUEUE_ALWAYS_ASYNC,
				     &usage->worker[i].src_addr,
				     &usage->worker[i].src_addr_len);
	if (status != PJ_EPENDING)
	    goto on_error;
    }

    pj_stun_server_register_usage(srv, usage);

    /* Only after everything has been initialized we copy the callback,
     * to prevent callback from being called when we encounter error
     * during initialiation (decendant would not expect this).
     */
    pj_memcpy(&usage->cb, cb, sizeof(*cb));

    *p_usage = usage;
    return PJ_SUCCESS;

on_error:
    pj_stun_usage_destroy(usage);
    return status;
}


/**
 * Destroy usage.
 */
PJ_DEF(pj_status_t) pj_stun_usage_destroy(pj_stun_usage *usage)
{
    pj_stun_server_unregister_usage(usage->srv, usage);
    if (usage->cb.on_destroy)
	(*usage->cb.on_destroy)(usage);

    if (usage->key) {
	pj_ioqueue_unregister(usage->key);
	usage->key = NULL;
	usage->sock = PJ_INVALID_SOCKET;
    } else if (usage->sock != 0 && usage->sock != PJ_INVALID_SOCKET) {
	pj_sock_close(usage->sock);
	usage->sock = PJ_INVALID_SOCKET;
    }

    if (usage->mutex) {
	pj_mutex_destroy(usage->mutex);
	usage->mutex = NULL;
    }

    if (usage->pool) {
	pj_pool_t *pool = usage->pool;
	usage->pool = NULL;
	pj_pool_release(pool);
    }

    return PJ_SUCCESS;
}


/**
 * Set user data.
 */
PJ_DEF(pj_status_t) pj_stun_usage_set_user_data( pj_stun_usage *usage,
						 void *user_data)
{
    usage->user_data = user_data;
    return PJ_SUCCESS;
}

/**
 * Get user data.
 */
PJ_DEF(void*) pj_stun_usage_get_user_data(pj_stun_usage *usage)
{
    return usage->user_data;
}


/**
 * Send with the usage.
 */
PJ_DEF(pj_status_t) pj_stun_usage_sendto( pj_stun_usage *usage,
					  const void *pkt,
					  pj_size_t pkt_size,
					  unsigned flags,
					  const pj_sockaddr_t *dst_addr,
					  unsigned addr_len)
{
    pj_ssize_t size = pkt_size;
    unsigned i, count = usage->send_count, index;

    pj_mutex_lock(usage->mutex);
    for (i=0, ++usage->send_index; i<count; ++i, ++usage->send_index) {
	if (usage->send_index >= usage->send_count)
	    usage->send_index = 0;

	if (pj_ioqueue_is_pending(usage->key, &usage->send_key[usage->send_index])==0) {
	    break;
	}
    }

    if (i==count) {
	pj_mutex_unlock(usage->mutex);
	return PJ_EBUSY;
    }

    index = usage->send_index;
    pj_mutex_unlock(usage->mutex);

    return pj_ioqueue_sendto(usage->key, &usage->send_key[index], 
			     pkt, &size, flags,
			     dst_addr, addr_len);
}


static void on_read_complete(pj_ioqueue_key_t *key, 
                             pj_ioqueue_op_key_t *op_key, 
                             pj_ssize_t bytes_read)
{
    enum { MAX_LOOP = 10 };
    pj_stun_usage *usage = (pj_stun_usage*) pj_ioqueue_get_user_data(key);
    struct worker *worker = (struct worker*) op_key;
    unsigned count;
    pj_status_t status;
    
    for (count=0; !usage->quitting; ++count) {
	unsigned flags;

	if (bytes_read > 0) {
	    (*usage->cb.on_rx_data)(usage, worker->readbuf, bytes_read,
				    &worker->src_addr, worker->src_addr_len);
	} else if (bytes_read < 0) {
	    pj_stun_perror(usage->pool->obj_name, "recv() error", -bytes_read);
	}

	if (usage->quitting)
	    break;

	bytes_read = sizeof(worker->readbuf);
	flags = (count >= MAX_LOOP) ? PJ_IOQUEUE_ALWAYS_ASYNC : 0;
	worker->src_addr_len = sizeof(worker->src_addr);
	status = pj_ioqueue_recvfrom(usage->key, &worker->read_key,
				     worker->readbuf, &bytes_read, flags,
				     &worker->src_addr, &worker->src_addr_len);
	if (status == PJ_EPENDING)
	    break;
    }
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩一区和二区| 亚洲精品伦理在线| 中文久久乱码一区二区| 亚洲免费资源在线播放| 人人狠狠综合久久亚洲| 亚洲国产色一区| 国产一区二区主播在线| 色哟哟在线观看一区二区三区| 成+人+亚洲+综合天堂| 欧美视频在线观看一区二区| 欧美性大战久久| 欧美国产精品一区二区三区| 一区二区三区在线观看欧美| 久久精品国产精品亚洲精品| 99久久99久久久精品齐齐| 日韩亚洲欧美成人一区| 亚洲欧美在线aaa| 久久99精品国产麻豆婷婷 | 麻豆精品在线观看| 91在线你懂得| 久久精品人人做| 日韩电影在线免费| 在线观看www91| 国产精品日韩精品欧美在线| 久热成人在线视频| 成人性生交大片免费| 日韩午夜激情视频| 国产精品电影一区二区| 韩国欧美国产1区| 欧美日韩二区三区| 亚洲一区在线观看免费| 成人app下载| 国产精品人成在线观看免费| 久久国产视频网| 欧美麻豆精品久久久久久| 有码一区二区三区| 成人晚上爱看视频| 久久精品日韩一区二区三区| 麻豆精品久久久| 欧美精品tushy高清| 亚洲国产你懂的| 色狠狠桃花综合| 一个色综合av| 日本精品视频一区二区| 亚洲精品欧美激情| 91免费看`日韩一区二区| 国产精品每日更新| 成人爽a毛片一区二区免费| 中文字幕av不卡| 国产成人免费高清| 国产亚洲欧美一区在线观看| 国产精品亚洲成人| 亚洲国产精华液网站w| 成人一区在线观看| 国产精品麻豆99久久久久久| 99久久免费国产| 日韩色在线观看| 高清beeg欧美| 亚洲一二三专区| 亚洲精品在线免费观看视频| 国产aⅴ综合色| 亚洲一区二区三区激情| 欧美电影免费提供在线观看| 高潮精品一区videoshd| 亚洲成在线观看| 亚洲精品一区二区精华| 在线观看日韩电影| 国产主播一区二区三区| 一区二区三区成人| 久久综合精品国产一区二区三区 | 日韩精品国产精品| 国产欧美日韩激情| 欧美三级电影网站| 国产成人av资源| 水野朝阳av一区二区三区| 国产精品久久久久9999吃药| 欧美日韩不卡一区二区| 成人av在线电影| 久色婷婷小香蕉久久| 亚洲美女在线国产| 久久精品无码一区二区三区 | 国产成人精品网址| 亚洲成av人影院| 国产精品国产三级国产普通话蜜臀| 欧美妇女性影城| 色综合色综合色综合色综合色综合| 久久精品国产99国产| 亚洲成人综合网站| 亚洲天堂免费看| 精品国产免费一区二区三区四区 | 欧美不卡在线视频| 欧美性感一类影片在线播放| 成人福利在线看| 国内精品久久久久影院薰衣草| 亚洲电影视频在线| 亚洲精品国久久99热| 日韩一区中文字幕| 国产精品久久综合| 久久久天堂av| 日韩视频永久免费| 5月丁香婷婷综合| 欧美日韩一区二区在线视频| 91色视频在线| 91伊人久久大香线蕉| 国产超碰在线一区| 国产成人鲁色资源国产91色综 | 欧美精品vⅰdeose4hd| 在线观看91精品国产入口| 91在线精品一区二区三区| 懂色av一区二区三区免费看| 韩国毛片一区二区三区| 免费av成人在线| 免费人成黄页网站在线一区二区 | 亚洲在线视频网站| 一区二区高清在线| 亚洲影视在线播放| 一区二区三区高清在线| 亚洲国产视频a| 性感美女极品91精品| 日韩av午夜在线观看| 蜜桃av一区二区| 韩国精品主播一区二区在线观看 | 美女脱光内衣内裤视频久久网站 | caoporen国产精品视频| 成人高清免费观看| 91免费版pro下载短视频| 色哦色哦哦色天天综合| 欧美乱熟臀69xxxxxx| 欧美精品一级二级| 欧美一区2区视频在线观看| 欧美一区欧美二区| 久久久久久久综合| 中文字幕欧美一区| 亚洲成人先锋电影| 国产乱人伦精品一区二区在线观看| 国产一区二区影院| 成人教育av在线| 欧美性受xxxx黑人xyx性爽| 日韩午夜在线观看视频| 国产欧美一区二区精品忘忧草 | 日本福利一区二区| 538在线一区二区精品国产| 久久综合资源网| 亚洲欧洲三级电影| 日本不卡123| 成人一区二区视频| 337p亚洲精品色噜噜狠狠| 久久综合色一综合色88| 成人欧美一区二区三区黑人麻豆| 午夜精品在线视频一区| 国产在线精品一区在线观看麻豆| a美女胸又www黄视频久久| 欧美一区二区视频网站| 亚洲欧洲成人av每日更新| 午夜精品爽啪视频| 波多野结衣一区二区三区| 欧美日韩国产天堂| 国产精品婷婷午夜在线观看| 天天综合网 天天综合色| 成人精品一区二区三区中文字幕| 欧美日韩大陆一区二区| 国产精品欧美久久久久一区二区| 亚洲国产视频在线| 99国产精品视频免费观看| 欧美成人综合网站| 亚洲高清中文字幕| 成人国产精品免费| 欧美精品一区二区三区蜜桃 | 国产精品自在在线| 欧美裸体bbwbbwbbw| 国产精品美女久久久久aⅴ国产馆| 日韩精品视频网| 欧美午夜精品久久久久久孕妇| 久久久精品综合| 日本美女一区二区| 欧美日本一道本| 一区二区三区精密机械公司| 成人激情小说乱人伦| 精品处破学生在线二十三| 首页综合国产亚洲丝袜| 在线欧美日韩精品| 18成人在线观看| 成人黄色大片在线观看| 久久色中文字幕| 老司机免费视频一区二区| 欧美一区二区三区在线看| 亚洲韩国一区二区三区| 91网址在线看| 国产精品沙发午睡系列990531| 久久99精品久久久久久国产越南| 91精品欧美久久久久久动漫| 国内精品久久久久影院薰衣草| 日韩欧美综合在线| 日韩综合在线视频| 欧美日韩三级在线| 亚洲另类春色校园小说| 欧美色爱综合网| 亚洲小少妇裸体bbw| 欧美视频一区二区在线观看| 亚洲国产日韩一级|