mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
use libco instead of state-thread(st), still have some bug
This commit is contained in:
parent
51d6c367f5
commit
7c8a35aea9
88 changed files with 4836 additions and 19273 deletions
1
trunk/3rdparty/libco/.gitignore
vendored
Normal file
1
trunk/3rdparty/libco/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
README.md
|
55
trunk/3rdparty/libco/CMakeLists.txt
vendored
Normal file
55
trunk/3rdparty/libco/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(libco)
|
||||
|
||||
# This for mac osx only
|
||||
set(CMAKE_MACOSX_RPATH 0)
|
||||
|
||||
# Set lib version
|
||||
set(LIBCO_VERSION 0.5)
|
||||
|
||||
# Set cflags
|
||||
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -g -fno-strict-aliasing -O2 -Wall -export-dynamic -Wall -pipe -D_GNU_SOURCE -D_REENTRANT -fPIC -Wno-deprecated -m64)
|
||||
|
||||
# Use c and asm
|
||||
enable_language(C ASM)
|
||||
|
||||
# Add source files
|
||||
set(SOURCE_FILES
|
||||
co_epoll.cpp
|
||||
co_hook_sys_call.cpp
|
||||
co_routine.cpp
|
||||
coctx.cpp
|
||||
coctx_swap.S)
|
||||
|
||||
# Add static and shared library target
|
||||
add_library(colib_static STATIC ${SOURCE_FILES})
|
||||
add_library(colib_shared SHARED ${SOURCE_FILES})
|
||||
|
||||
# Set library output name
|
||||
set_target_properties(colib_static PROPERTIES OUTPUT_NAME colib)
|
||||
set_target_properties(colib_shared PROPERTIES OUTPUT_NAME colib)
|
||||
|
||||
set_target_properties(colib_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
set_target_properties(colib_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
|
||||
# Set shared library version, will generate libcolib.${LIBCO_VERSION}.so and a symbol link named libcolib.so
|
||||
# For mac osx, the extension name will be .dylib
|
||||
set_target_properties(colib_shared PROPERTIES VERSION ${LIBCO_VERSION} SOVERSION ${LIBCO_VERSION})
|
||||
|
||||
|
||||
|
||||
# Macro for add example target
|
||||
macro(add_example_target EXAMPLE_TARGET)
|
||||
add_executable("example_${EXAMPLE_TARGET}" "example_${EXAMPLE_TARGET}.cpp")
|
||||
target_link_libraries("example_${EXAMPLE_TARGET}" colib_static pthread dl)
|
||||
endmacro(add_example_target)
|
||||
|
||||
add_example_target(closure)
|
||||
add_example_target(cond)
|
||||
add_example_target(copystack)
|
||||
add_example_target(echocli)
|
||||
add_example_target(echosvr)
|
||||
add_example_target(poll)
|
||||
add_example_target(setenv)
|
||||
add_example_target(specific)
|
||||
add_example_target(thread)
|
BIN
trunk/3rdparty/libco/LICENSE.txt
vendored
Normal file
BIN
trunk/3rdparty/libco/LICENSE.txt
vendored
Normal file
Binary file not shown.
84
trunk/3rdparty/libco/Makefile
vendored
Normal file
84
trunk/3rdparty/libco/Makefile
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
# Tencent is pleased to support the open source community by making Libco available.
|
||||
#
|
||||
# Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
COMM_MAKE = 1
|
||||
COMM_ECHO = 1
|
||||
version=0.5
|
||||
v=debug
|
||||
include co.mk
|
||||
|
||||
########## options ##########
|
||||
CFLAGS += -g -fno-strict-aliasing -O2 -Wall -export-dynamic \
|
||||
-Wall -pipe -D_GNU_SOURCE -D_REENTRANT -fPIC -Wno-deprecated -m64
|
||||
|
||||
UNAME := $(shell uname -s)
|
||||
|
||||
ifeq ($(UNAME), FreeBSD)
|
||||
LINKS += -g -L./lib -lcolib -lpthread
|
||||
else
|
||||
LINKS += -g -L./lib -lcolib -lpthread -ldl
|
||||
endif
|
||||
|
||||
COLIB_OBJS=co_epoll.o co_routine.o co_hook_sys_call.o coctx_swap.o coctx.o
|
||||
#co_swapcontext.o
|
||||
|
||||
PROGS = colib example_poll example_echosvr example_echocli example_thread example_cond example_specific example_copystack example_closure
|
||||
|
||||
all:$(PROGS)
|
||||
|
||||
colib:libcolib.a libcolib.so
|
||||
|
||||
libcolib.a: $(COLIB_OBJS)
|
||||
$(ARSTATICLIB)
|
||||
libcolib.so: $(COLIB_OBJS)
|
||||
$(BUILDSHARELIB)
|
||||
|
||||
example_echosvr:example_echosvr.o
|
||||
$(BUILDEXE)
|
||||
example_echocli:example_echocli.o
|
||||
$(BUILDEXE)
|
||||
example_thread:example_thread.o
|
||||
$(BUILDEXE)
|
||||
example_poll:example_poll.o
|
||||
$(BUILDEXE)
|
||||
example_exit:example_exit.o
|
||||
$(BUILDEXE)
|
||||
example_cond:example_cond.o
|
||||
$(BUILDEXE)
|
||||
example_specific:example_specific.o
|
||||
$(BUILDEXE)
|
||||
example_copystack:example_copystack.o
|
||||
$(BUILDEXE)
|
||||
example_setenv:example_setenv.o
|
||||
$(BUILDEXE)
|
||||
example_closure:example_closure.o
|
||||
$(BUILDEXE)
|
||||
|
||||
dist: clean libco-$(version).src.tar.gz
|
||||
|
||||
libco-$(version).src.tar.gz:
|
||||
@find . -type f | grep -v CVS | grep -v .svn | sed s:^./:libco-$(version)/: > MANIFEST
|
||||
@(cd ..; ln -s libco_pub libco-$(version))
|
||||
(cd ..; tar cvf - `cat libco_pub/MANIFEST` | gzip > libco_pub/libco-$(version).src.tar.gz)
|
||||
@(cd ..; rm libco-$(version))
|
||||
|
||||
clean:
|
||||
$(CLEAN) *.o $(PROGS)
|
||||
rm -fr MANIFEST lib solib libco-$(version).src.tar.gz libco-$(version)
|
||||
|
85
trunk/3rdparty/libco/co.mk
vendored
Normal file
85
trunk/3rdparty/libco/co.mk
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
#
|
||||
# Tencent is pleased to support the open source community by making Libco available.
|
||||
#
|
||||
# Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
|
||||
##### Makefile Rules ##########
|
||||
MAIL_ROOT=.
|
||||
SRCROOT=.
|
||||
|
||||
##define the compliers
|
||||
CPP = $(CXX)
|
||||
AR = ar -rc
|
||||
RANLIB = ranlib
|
||||
|
||||
CPPSHARE = $(CPP) -fPIC -shared -O2 -pipe -L$(SRCROOT)/solib/ -o
|
||||
CSHARE = $(CC) -fPIC -shared -O2 -pipe -L$(SRCROOT)/solib/ -o
|
||||
|
||||
ifeq ($v,release)
|
||||
CFLAGS= -O2 $(INCLS) -fPIC -DLINUX -pipe -Wno-deprecated -c
|
||||
else
|
||||
CFLAGS= -g $(INCLS) -fPIC -DLINUX -pipe -c -fno-inline
|
||||
endif
|
||||
|
||||
ifneq ($v,release)
|
||||
BFLAGS= -g
|
||||
endif
|
||||
|
||||
STATICLIBPATH=$(SRCROOT)/lib
|
||||
DYNAMICLIBPATH=$(SRCROOT)/solib
|
||||
|
||||
INCLS += -I$(SRCROOT)
|
||||
|
||||
## default links
|
||||
ifeq ($(LINKS_DYNAMIC), 1)
|
||||
LINKS += -L$(DYNAMICLIBPATH) -L$(STATICLIBPATH)
|
||||
else
|
||||
LINKS += -L$(STATICLIBPATH)
|
||||
endif
|
||||
|
||||
CPPSRCS = $(wildcard *.cpp)
|
||||
CSRCS = $(wildcard *.c)
|
||||
CPPOBJS = $(patsubst %.cpp,%.o,$(CPPSRCS))
|
||||
COBJS = $(patsubst %.c,%.o,$(CSRCS))
|
||||
|
||||
SRCS = $(CPPSRCS) $(CSRCS)
|
||||
OBJS = $(CPPOBJS) $(COBJS)
|
||||
|
||||
CPPCOMPI=$(CPP) $(CFLAGS) -Wno-deprecated
|
||||
CCCOMPI=$(CC) $(CFLAGS)
|
||||
|
||||
BUILDEXE = $(CPP) $(BFLAGS) -o $@ $^ $(LINKS)
|
||||
CLEAN = rm -f *.o
|
||||
|
||||
CPPCOMPILE = $(CPPCOMPI) $< $(FLAGS) $(INCLS) $(MTOOL_INCL) -o $@
|
||||
CCCOMPILE = $(CCCOMPI) $< $(FLAGS) $(INCLS) $(MTOOL_INCL) -o $@
|
||||
|
||||
ARSTATICLIB = $(AR) $@.tmp $^ $(AR_FLAGS); \
|
||||
if [ $$? -ne 0 ]; then exit 1; fi; \
|
||||
test -d $(STATICLIBPATH) || mkdir -p $(STATICLIBPATH); \
|
||||
mv -f $@.tmp $(STATICLIBPATH)/$@;
|
||||
|
||||
BUILDSHARELIB = $(CPPSHARE) $@.tmp $^ $(BS_FLAGS); \
|
||||
if [ $$? -ne 0 ]; then exit 1; fi; \
|
||||
test -d $(DYNAMICLIBPATH) || mkdir -p $(DYNAMICLIBPATH); \
|
||||
mv -f $@.tmp $(DYNAMICLIBPATH)/$@;
|
||||
|
||||
.cpp.o:
|
||||
$(CPPCOMPILE)
|
||||
.c.o:
|
||||
$(CCCOMPILE)
|
96
trunk/3rdparty/libco/co_closure.h
vendored
Normal file
96
trunk/3rdparty/libco/co_closure.h
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CO_CLOSURE_H__
|
||||
#define __CO_CLOSURE_H__
|
||||
struct stCoClosure_t
|
||||
{
|
||||
public:
|
||||
virtual void exec() = 0;
|
||||
};
|
||||
|
||||
//1.base
|
||||
//-- 1.1 comac_argc
|
||||
|
||||
#define comac_get_args_cnt( ... ) comac_arg_n( __VA_ARGS__ )
|
||||
#define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,N,...) N
|
||||
#define comac_args_seqs() 7,6,5,4,3,2,1,0
|
||||
#define comac_join_1( x,y ) x##y
|
||||
|
||||
#define comac_argc( ... ) comac_get_args_cnt( 0,##__VA_ARGS__,comac_args_seqs() )
|
||||
#define comac_join( x,y) comac_join_1( x,y )
|
||||
|
||||
//-- 1.2 repeat
|
||||
#define repeat_0( fun,a,... )
|
||||
#define repeat_1( fun,a,... ) fun( 1,a,__VA_ARGS__ ) repeat_0( fun,__VA_ARGS__ )
|
||||
#define repeat_2( fun,a,... ) fun( 2,a,__VA_ARGS__ ) repeat_1( fun,__VA_ARGS__ )
|
||||
#define repeat_3( fun,a,... ) fun( 3,a,__VA_ARGS__ ) repeat_2( fun,__VA_ARGS__ )
|
||||
#define repeat_4( fun,a,... ) fun( 4,a,__VA_ARGS__ ) repeat_3( fun,__VA_ARGS__ )
|
||||
#define repeat_5( fun,a,... ) fun( 5,a,__VA_ARGS__ ) repeat_4( fun,__VA_ARGS__ )
|
||||
#define repeat_6( fun,a,... ) fun( 6,a,__VA_ARGS__ ) repeat_5( fun,__VA_ARGS__ )
|
||||
|
||||
#define repeat( n,fun,... ) comac_join( repeat_,n )( fun,__VA_ARGS__)
|
||||
|
||||
//2.implement
|
||||
#if __cplusplus <= 199711L
|
||||
#define decl_typeof( i,a,... ) typedef typeof( a ) typeof_##a;
|
||||
#else
|
||||
#define decl_typeof( i,a,... ) typedef decltype( a ) typeof_##a;
|
||||
#endif
|
||||
#define impl_typeof( i,a,... ) typeof_##a & a;
|
||||
#define impl_typeof_cpy( i,a,... ) typeof_##a a;
|
||||
#define con_param_typeof( i,a,... ) typeof_##a & a##r,
|
||||
#define param_init_typeof( i,a,... ) a(a##r),
|
||||
|
||||
|
||||
//2.1 reference
|
||||
|
||||
#define co_ref( name,... )\
|
||||
repeat( comac_argc(__VA_ARGS__) ,decl_typeof,__VA_ARGS__ )\
|
||||
class type_##name\
|
||||
{\
|
||||
public:\
|
||||
repeat( comac_argc(__VA_ARGS__) ,impl_typeof,__VA_ARGS__ )\
|
||||
int _member_cnt;\
|
||||
type_##name( \
|
||||
repeat( comac_argc(__VA_ARGS__),con_param_typeof,__VA_ARGS__ ) ... ): \
|
||||
repeat( comac_argc(__VA_ARGS__),param_init_typeof,__VA_ARGS__ ) _member_cnt(comac_argc(__VA_ARGS__)) \
|
||||
{}\
|
||||
} name( __VA_ARGS__ ) ;
|
||||
|
||||
|
||||
//2.2 function
|
||||
|
||||
#define co_func(name,...)\
|
||||
repeat( comac_argc(__VA_ARGS__) ,decl_typeof,__VA_ARGS__ )\
|
||||
class name:public stCoClosure_t\
|
||||
{\
|
||||
public:\
|
||||
repeat( comac_argc(__VA_ARGS__) ,impl_typeof_cpy,__VA_ARGS__ )\
|
||||
int _member_cnt;\
|
||||
public:\
|
||||
name( repeat( comac_argc(__VA_ARGS__),con_param_typeof,__VA_ARGS__ ) ... ): \
|
||||
repeat( comac_argc(__VA_ARGS__),param_init_typeof,__VA_ARGS__ ) _member_cnt(comac_argc(__VA_ARGS__))\
|
||||
{}\
|
||||
void exec()
|
||||
|
||||
#define co_func_end }
|
||||
|
||||
|
||||
#endif
|
||||
|
318
trunk/3rdparty/libco/co_epoll.cpp
vendored
Normal file
318
trunk/3rdparty/libco/co_epoll.cpp
vendored
Normal file
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "co_epoll.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined( __APPLE__ ) && !defined( __FreeBSD__ )
|
||||
|
||||
int co_epoll_wait( int epfd,struct co_epoll_res *events,int maxevents,int timeout )
|
||||
{
|
||||
return epoll_wait( epfd,events->events,maxevents,timeout );
|
||||
}
|
||||
int co_epoll_ctl( int epfd,int op,int fd,struct epoll_event * ev )
|
||||
{
|
||||
return epoll_ctl( epfd,op,fd,ev );
|
||||
}
|
||||
int co_epoll_create( int size )
|
||||
{
|
||||
return epoll_create( size );
|
||||
}
|
||||
|
||||
struct co_epoll_res *co_epoll_res_alloc( int n )
|
||||
{
|
||||
struct co_epoll_res * ptr =
|
||||
(struct co_epoll_res *)malloc( sizeof( struct co_epoll_res ) );
|
||||
|
||||
ptr->size = n;
|
||||
ptr->events = (struct epoll_event*)calloc( 1,n * sizeof( struct epoll_event ) );
|
||||
|
||||
return ptr;
|
||||
|
||||
}
|
||||
void co_epoll_res_free( struct co_epoll_res * ptr )
|
||||
{
|
||||
if( !ptr ) return;
|
||||
if( ptr->events ) free( ptr->events );
|
||||
free( ptr );
|
||||
}
|
||||
|
||||
#else
|
||||
class clsFdMap // million of fd , 1024 * 1024
|
||||
{
|
||||
private:
|
||||
static const int row_size = 1024;
|
||||
static const int col_size = 1024;
|
||||
|
||||
void **m_pp[ 1024 ];
|
||||
public:
|
||||
clsFdMap()
|
||||
{
|
||||
memset( m_pp,0,sizeof(m_pp) );
|
||||
}
|
||||
~clsFdMap()
|
||||
{
|
||||
for(int i=0;i<sizeof(m_pp)/sizeof(m_pp[0]);i++)
|
||||
{
|
||||
if( m_pp[i] )
|
||||
{
|
||||
free( m_pp[i] );
|
||||
m_pp[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline int clear( int fd )
|
||||
{
|
||||
set( fd,NULL );
|
||||
return 0;
|
||||
}
|
||||
inline int set( int fd,const void * ptr )
|
||||
{
|
||||
int idx = fd / row_size;
|
||||
if( idx < 0 || idx >= sizeof(m_pp)/sizeof(m_pp[0]) )
|
||||
{
|
||||
assert( __LINE__ == 0 );
|
||||
return -__LINE__;
|
||||
}
|
||||
if( !m_pp[ idx ] )
|
||||
{
|
||||
m_pp[ idx ] = (void**)calloc( 1,sizeof(void*) * col_size );
|
||||
}
|
||||
m_pp[ idx ][ fd % col_size ] = (void*)ptr;
|
||||
return 0;
|
||||
}
|
||||
inline void *get( int fd )
|
||||
{
|
||||
int idx = fd / row_size;
|
||||
if( idx < 0 || idx >= sizeof(m_pp)/sizeof(m_pp[0]) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void **lp = m_pp[ idx ];
|
||||
if( !lp ) return NULL;
|
||||
|
||||
return lp[ fd % col_size ];
|
||||
}
|
||||
};
|
||||
|
||||
__thread clsFdMap *s_fd_map = NULL;
|
||||
|
||||
static inline clsFdMap *get_fd_map()
|
||||
{
|
||||
if( !s_fd_map )
|
||||
{
|
||||
s_fd_map = new clsFdMap();
|
||||
}
|
||||
return s_fd_map;
|
||||
}
|
||||
|
||||
struct kevent_pair_t
|
||||
{
|
||||
int fire_idx;
|
||||
int events;
|
||||
uint64_t u64;
|
||||
};
|
||||
int co_epoll_create( int size )
|
||||
{
|
||||
return kqueue();
|
||||
}
|
||||
int co_epoll_wait( int epfd,struct co_epoll_res *events,int maxevents,int timeout )
|
||||
{
|
||||
struct timespec t = { 0 };
|
||||
if( timeout > 0 )
|
||||
{
|
||||
t.tv_sec = timeout;
|
||||
}
|
||||
int ret = kevent( epfd,
|
||||
NULL, 0, //register null
|
||||
events->eventlist, maxevents,//just retrival
|
||||
( -1 == timeout ) ? NULL : &t );
|
||||
int j = 0;
|
||||
for(int i=0;i<ret;i++)
|
||||
{
|
||||
struct kevent &kev = events->eventlist[i];
|
||||
struct kevent_pair_t *ptr = (struct kevent_pair_t*)kev.udata;
|
||||
struct epoll_event *ev = events->events + i;
|
||||
if( 0 == ptr->fire_idx )
|
||||
{
|
||||
ptr->fire_idx = i + 1;
|
||||
memset( ev,0,sizeof(*ev) );
|
||||
++j;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev = events->events + ptr->fire_idx - 1;
|
||||
}
|
||||
if( EVFILT_READ == kev.filter )
|
||||
{
|
||||
ev->events |= EPOLLIN;
|
||||
}
|
||||
else if( EVFILT_WRITE == kev.filter )
|
||||
{
|
||||
ev->events |= EPOLLOUT;
|
||||
}
|
||||
ev->data.u64 = ptr->u64;
|
||||
}
|
||||
for(int i=0;i<ret;i++)
|
||||
{
|
||||
(( struct kevent_pair_t* )(events->eventlist[i].udata) )->fire_idx = 0;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
int co_epoll_del( int epfd,int fd )
|
||||
{
|
||||
|
||||
struct timespec t = { 0 };
|
||||
struct kevent_pair_t *ptr = ( struct kevent_pair_t* )get_fd_map()->get( fd );
|
||||
if( !ptr ) return 0;
|
||||
if( EPOLLIN & ptr->events )
|
||||
{
|
||||
struct kevent kev = { 0 };
|
||||
kev.ident = fd;
|
||||
kev.filter = EVFILT_READ;
|
||||
kev.flags = EV_DELETE;
|
||||
kevent( epfd,&kev,1, NULL,0,&t );
|
||||
}
|
||||
if( EPOLLOUT & ptr->events )
|
||||
{
|
||||
struct kevent kev = { 0 };
|
||||
kev.ident = fd;
|
||||
kev.filter = EVFILT_WRITE;
|
||||
kev.flags = EV_DELETE;
|
||||
kevent( epfd,&kev,1, NULL,0,&t );
|
||||
}
|
||||
get_fd_map()->clear( fd );
|
||||
free( ptr );
|
||||
return 0;
|
||||
}
|
||||
int co_epoll_ctl( int epfd,int op,int fd,struct epoll_event * ev )
|
||||
{
|
||||
if( EPOLL_CTL_DEL == op )
|
||||
{
|
||||
return co_epoll_del( epfd,fd );
|
||||
}
|
||||
|
||||
const int flags = ( EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP );
|
||||
if( ev->events & ~flags )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( EPOLL_CTL_ADD == op && get_fd_map()->get( fd ) )
|
||||
{
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
else if( EPOLL_CTL_MOD == op && !get_fd_map()->get( fd ) )
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct kevent_pair_t *ptr = (struct kevent_pair_t*)get_fd_map()->get( fd );
|
||||
if( !ptr )
|
||||
{
|
||||
ptr = (kevent_pair_t*)calloc(1,sizeof(kevent_pair_t));
|
||||
get_fd_map()->set( fd,ptr );
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
struct timespec t = { 0 };
|
||||
|
||||
// printf("ptr->events 0x%X\n",ptr->events);
|
||||
|
||||
if( EPOLL_CTL_MOD == op )
|
||||
{
|
||||
//1.delete if exists
|
||||
if( ptr->events & EPOLLIN )
|
||||
{
|
||||
struct kevent kev = { 0 };
|
||||
EV_SET( &kev,fd,EVFILT_READ,EV_DELETE,0,0,NULL );
|
||||
kevent( epfd, &kev,1, NULL,0, &t );
|
||||
}
|
||||
//1.delete if exists
|
||||
if( ptr->events & EPOLLOUT )
|
||||
{
|
||||
struct kevent kev = { 0 };
|
||||
EV_SET( &kev,fd,EVFILT_WRITE,EV_DELETE,0,0,NULL );
|
||||
ret = kevent( epfd, &kev,1, NULL,0, &t );
|
||||
// printf("delete write ret %d\n",ret );
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if( ev->events & EPOLLIN )
|
||||
{
|
||||
|
||||
//2.add
|
||||
struct kevent kev = { 0 };
|
||||
EV_SET( &kev,fd,EVFILT_READ,EV_ADD,0,0,ptr );
|
||||
ret = kevent( epfd, &kev,1, NULL,0, &t );
|
||||
if( ret ) break;
|
||||
}
|
||||
if( ev->events & EPOLLOUT )
|
||||
{
|
||||
//2.add
|
||||
struct kevent kev = { 0 };
|
||||
EV_SET( &kev,fd,EVFILT_WRITE,EV_ADD,0,0,ptr );
|
||||
ret = kevent( epfd, &kev,1, NULL,0, &t );
|
||||
if( ret ) break;
|
||||
}
|
||||
} while( 0 );
|
||||
|
||||
if( ret )
|
||||
{
|
||||
get_fd_map()->clear( fd );
|
||||
free( ptr );
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptr->events = ev->events;
|
||||
ptr->u64 = ev->data.u64;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct co_epoll_res *co_epoll_res_alloc( int n )
|
||||
{
|
||||
struct co_epoll_res * ptr =
|
||||
(struct co_epoll_res *)malloc( sizeof( struct co_epoll_res ) );
|
||||
|
||||
ptr->size = n;
|
||||
ptr->events = (struct epoll_event*)calloc( 1,n * sizeof( struct epoll_event ) );
|
||||
ptr->eventlist = (struct kevent*)calloc( 1,n * sizeof( struct kevent) );
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void co_epoll_res_free( struct co_epoll_res * ptr )
|
||||
{
|
||||
if( !ptr ) return;
|
||||
if( ptr->events ) free( ptr->events );
|
||||
if( ptr->eventlist ) free( ptr->eventlist );
|
||||
free( ptr );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
93
trunk/3rdparty/libco/co_epoll.h
vendored
Normal file
93
trunk/3rdparty/libco/co_epoll.h
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CO_EPOLL_H__
|
||||
#define __CO_EPOLL_H__
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <time.h>
|
||||
|
||||
#if !defined( __APPLE__ ) && !defined( __FreeBSD__ )
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
struct co_epoll_res
|
||||
{
|
||||
int size;
|
||||
struct epoll_event *events;
|
||||
struct kevent *eventlist;
|
||||
};
|
||||
int co_epoll_wait( int epfd,struct co_epoll_res *events,int maxevents,int timeout );
|
||||
int co_epoll_ctl( int epfd,int op,int fd,struct epoll_event * );
|
||||
int co_epoll_create( int size );
|
||||
struct co_epoll_res *co_epoll_res_alloc( int n );
|
||||
void co_epoll_res_free( struct co_epoll_res * );
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/event.h>
|
||||
enum EPOLL_EVENTS
|
||||
{
|
||||
EPOLLIN = 0X001,
|
||||
EPOLLPRI = 0X002,
|
||||
EPOLLOUT = 0X004,
|
||||
|
||||
EPOLLERR = 0X008,
|
||||
EPOLLHUP = 0X010,
|
||||
|
||||
EPOLLRDNORM = 0x40,
|
||||
EPOLLWRNORM = 0x004,
|
||||
};
|
||||
#define EPOLL_CTL_ADD 1
|
||||
#define EPOLL_CTL_DEL 2
|
||||
#define EPOLL_CTL_MOD 3
|
||||
typedef union epoll_data
|
||||
{
|
||||
void *ptr;
|
||||
int fd;
|
||||
uint32_t u32;
|
||||
uint64_t u64;
|
||||
|
||||
} epoll_data_t;
|
||||
|
||||
struct epoll_event
|
||||
{
|
||||
uint32_t events;
|
||||
epoll_data_t data;
|
||||
};
|
||||
|
||||
struct co_epoll_res
|
||||
{
|
||||
int size;
|
||||
struct epoll_event *events;
|
||||
struct kevent *eventlist;
|
||||
};
|
||||
int co_epoll_wait( int epfd,struct co_epoll_res *events,int maxevents,int timeout );
|
||||
int co_epoll_ctl( int epfd,int op,int fd,struct epoll_event * );
|
||||
int co_epoll_create( int size );
|
||||
struct co_epoll_res *co_epoll_res_alloc( int n );
|
||||
void co_epoll_res_free( struct co_epoll_res * );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
1003
trunk/3rdparty/libco/co_hook_sys_call.cpp
vendored
Normal file
1003
trunk/3rdparty/libco/co_hook_sys_call.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
1196
trunk/3rdparty/libco/co_routine.cpp
vendored
Normal file
1196
trunk/3rdparty/libco/co_routine.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
93
trunk/3rdparty/libco/co_routine.h
vendored
Normal file
93
trunk/3rdparty/libco/co_routine.h
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CO_ROUTINE_H__
|
||||
#define __CO_ROUTINE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/poll.h>
|
||||
#include <pthread.h>
|
||||
|
||||
//1.struct
|
||||
|
||||
struct stCoRoutine_t;
|
||||
struct stShareStack_t;
|
||||
|
||||
struct stCoRoutineAttr_t
|
||||
{
|
||||
int stack_size;
|
||||
stShareStack_t* share_stack;
|
||||
stCoRoutineAttr_t()
|
||||
{
|
||||
stack_size = 128 * 1024;
|
||||
share_stack = NULL;
|
||||
}
|
||||
}__attribute__ ((packed));
|
||||
|
||||
struct stCoEpoll_t;
|
||||
typedef int (*pfn_co_eventloop_t)(void *);
|
||||
typedef void *(*pfn_co_routine_t)( void * );
|
||||
|
||||
//2.co_routine
|
||||
|
||||
int co_create( stCoRoutine_t **co,const stCoRoutineAttr_t *attr,void *(*routine)(void*),void *arg );
|
||||
void co_resume( stCoRoutine_t *co );
|
||||
void co_yield( stCoRoutine_t *co );
|
||||
void co_yield_ct(); //ct = current thread
|
||||
void co_release( stCoRoutine_t *co );
|
||||
void co_reset(stCoRoutine_t * co);
|
||||
|
||||
stCoRoutine_t *co_self();
|
||||
|
||||
int co_poll( stCoEpoll_t *ctx,struct pollfd fds[], nfds_t nfds, int timeout_ms );
|
||||
void co_eventloop( stCoEpoll_t *ctx,pfn_co_eventloop_t pfn,void *arg );
|
||||
|
||||
//3.specific
|
||||
|
||||
int co_setspecific( pthread_key_t key, const void *value );
|
||||
void * co_getspecific( pthread_key_t key );
|
||||
|
||||
//4.event
|
||||
|
||||
stCoEpoll_t * co_get_epoll_ct(); //ct = current thread
|
||||
|
||||
//5.hook syscall ( poll/read/write/recv/send/recvfrom/sendto )
|
||||
|
||||
void co_enable_hook_sys();
|
||||
void co_disable_hook_sys();
|
||||
bool co_is_enable_sys_hook();
|
||||
|
||||
//6.sync
|
||||
struct stCoCond_t;
|
||||
|
||||
stCoCond_t *co_cond_alloc();
|
||||
int co_cond_free( stCoCond_t * cc );
|
||||
|
||||
int co_cond_signal( stCoCond_t * );
|
||||
int co_cond_broadcast( stCoCond_t * );
|
||||
int co_cond_timedwait( stCoCond_t *,int timeout_ms );
|
||||
|
||||
//7.share stack
|
||||
stShareStack_t* co_alloc_sharestack(int iCount, int iStackSize);
|
||||
|
||||
//8.init envlist for hook get/set env
|
||||
void co_set_env_list( const char *name[],size_t cnt);
|
||||
|
||||
void co_log_err( const char *fmt,... );
|
||||
#endif
|
||||
|
111
trunk/3rdparty/libco/co_routine_inner.h
vendored
Normal file
111
trunk/3rdparty/libco/co_routine_inner.h
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CO_ROUTINE_INNER_H__
|
||||
|
||||
#include "co_routine.h"
|
||||
#include "coctx.h"
|
||||
struct stCoRoutineEnv_t;
|
||||
struct stCoSpec_t
|
||||
{
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct stStackMem_t
|
||||
{
|
||||
stCoRoutine_t* occupy_co;
|
||||
int stack_size;
|
||||
char* stack_bp; //stack_buffer + stack_size
|
||||
char* stack_buffer;
|
||||
|
||||
};
|
||||
|
||||
struct stShareStack_t
|
||||
{
|
||||
unsigned int alloc_idx;
|
||||
int stack_size;
|
||||
int count;
|
||||
stStackMem_t** stack_array;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct stCoRoutine_t
|
||||
{
|
||||
stCoRoutineEnv_t *env;
|
||||
pfn_co_routine_t pfn;
|
||||
void *arg;
|
||||
coctx_t ctx;
|
||||
|
||||
char cStart;
|
||||
char cEnd;
|
||||
char cIsMain;
|
||||
char cEnableSysHook;
|
||||
char cIsShareStack;
|
||||
|
||||
void *pvEnv;
|
||||
|
||||
//char sRunStack[ 1024 * 128 ];
|
||||
stStackMem_t* stack_mem;
|
||||
|
||||
|
||||
//save satck buffer while confilct on same stack_buffer;
|
||||
char* stack_sp;
|
||||
unsigned int save_size;
|
||||
char* save_buffer;
|
||||
|
||||
stCoSpec_t aSpec[1024];
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//1.env
|
||||
void co_init_curr_thread_env();
|
||||
stCoRoutineEnv_t * co_get_curr_thread_env();
|
||||
|
||||
//2.coroutine
|
||||
void co_free( stCoRoutine_t * co );
|
||||
void co_yield_env( stCoRoutineEnv_t *env );
|
||||
|
||||
//3.func
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
struct stTimeout_t;
|
||||
struct stTimeoutItem_t ;
|
||||
|
||||
stTimeout_t *AllocTimeout( int iSize );
|
||||
void FreeTimeout( stTimeout_t *apTimeout );
|
||||
int AddTimeout( stTimeout_t *apTimeout,stTimeoutItem_t *apItem ,uint64_t allNow );
|
||||
|
||||
struct stCoEpoll_t;
|
||||
stCoEpoll_t * AllocEpoll();
|
||||
void FreeEpoll( stCoEpoll_t *ctx );
|
||||
|
||||
stCoRoutine_t * GetCurrThreadCo();
|
||||
void SetEpoll( stCoRoutineEnv_t *env,stCoEpoll_t *ev );
|
||||
|
||||
typedef void (*pfnCoRoutineFunc_t)();
|
||||
|
||||
#endif
|
||||
|
||||
#define __CO_ROUTINE_INNER_H__
|
86
trunk/3rdparty/libco/co_routine_specific.h
vendored
Normal file
86
trunk/3rdparty/libco/co_routine_specific.h
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
invoke only once in the whole program
|
||||
CoRoutineSetSpecificCallBack(CoRoutineGetSpecificFunc_t pfnGet,CoRoutineSetSpecificFunc_t pfnSet)
|
||||
|
||||
struct MyData_t
|
||||
{
|
||||
int iValue;
|
||||
char szValue[100];
|
||||
};
|
||||
CO_ROUTINE_SPECIFIC( MyData_t,__routine );
|
||||
|
||||
int main()
|
||||
{
|
||||
CoRoutineSetSpecificCallBack( co_getspecific,co_setspecific );
|
||||
|
||||
__routine->iValue = 10;
|
||||
strcpy( __routine->szValue,"hello world" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
extern int co_setspecific( pthread_key_t key, const void *value );
|
||||
extern void * co_getspecific( pthread_key_t key );
|
||||
|
||||
#define CO_ROUTINE_SPECIFIC( name,y ) \
|
||||
\
|
||||
static pthread_once_t _routine_once_##name = PTHREAD_ONCE_INIT; \
|
||||
static pthread_key_t _routine_key_##name;\
|
||||
static int _routine_init_##name = 0;\
|
||||
static void _routine_make_key_##name() \
|
||||
{\
|
||||
(void) pthread_key_create(&_routine_key_##name, NULL); \
|
||||
}\
|
||||
template <class T>\
|
||||
class clsRoutineData_routine_##name\
|
||||
{\
|
||||
public:\
|
||||
inline T *operator->()\
|
||||
{\
|
||||
if( !_routine_init_##name ) \
|
||||
{\
|
||||
pthread_once( &_routine_once_##name,_routine_make_key_##name );\
|
||||
_routine_init_##name = 1;\
|
||||
}\
|
||||
T* p = (T*)co_getspecific( _routine_key_##name );\
|
||||
if( !p )\
|
||||
{\
|
||||
p = (T*)calloc(1,sizeof( T ));\
|
||||
int ret = co_setspecific( _routine_key_##name,p) ;\
|
||||
if ( ret )\
|
||||
{\
|
||||
if ( p )\
|
||||
{\
|
||||
free(p);\
|
||||
p = NULL;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
return p;\
|
||||
}\
|
||||
};\
|
||||
\
|
||||
static clsRoutineData_routine_##name<name> y;
|
||||
|
132
trunk/3rdparty/libco/coctx.cpp
vendored
Normal file
132
trunk/3rdparty/libco/coctx.cpp
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco
|
||||
available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "coctx.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ESP 0
|
||||
#define EIP 1
|
||||
#define EAX 2
|
||||
#define ECX 3
|
||||
// -----------
|
||||
#define RSP 0
|
||||
#define RIP 1
|
||||
#define RBX 2
|
||||
#define RDI 3
|
||||
#define RSI 4
|
||||
|
||||
#define RBP 5
|
||||
#define R12 6
|
||||
#define R13 7
|
||||
#define R14 8
|
||||
#define R15 9
|
||||
#define RDX 10
|
||||
#define RCX 11
|
||||
#define R8 12
|
||||
#define R9 13
|
||||
|
||||
//----- --------
|
||||
// 32 bit
|
||||
// | regs[0]: ret |
|
||||
// | regs[1]: ebx |
|
||||
// | regs[2]: ecx |
|
||||
// | regs[3]: edx |
|
||||
// | regs[4]: edi |
|
||||
// | regs[5]: esi |
|
||||
// | regs[6]: ebp |
|
||||
// | regs[7]: eax | = esp
|
||||
enum {
|
||||
kEIP = 0,
|
||||
kEBP = 6,
|
||||
kESP = 7,
|
||||
};
|
||||
|
||||
//-------------
|
||||
// 64 bit
|
||||
// low | regs[0]: r15 |
|
||||
// | regs[1]: r14 |
|
||||
// | regs[2]: r13 |
|
||||
// | regs[3]: r12 |
|
||||
// | regs[4]: r9 |
|
||||
// | regs[5]: r8 |
|
||||
// | regs[6]: rbp |
|
||||
// | regs[7]: rdi |
|
||||
// | regs[8]: rsi |
|
||||
// | regs[9]: ret | //ret func addr
|
||||
// | regs[10]: rdx |
|
||||
// | regs[11]: rcx |
|
||||
// | regs[12]: rbx |
|
||||
// hig | regs[13]: rsp |
|
||||
enum {
|
||||
kRDI = 7,
|
||||
kRSI = 8,
|
||||
kRETAddr = 9,
|
||||
kRSP = 13,
|
||||
};
|
||||
|
||||
// 64 bit
|
||||
extern "C" {
|
||||
extern void coctx_swap(coctx_t*, coctx_t*) asm("coctx_swap");
|
||||
};
|
||||
#if defined(__i386__)
|
||||
int coctx_init(coctx_t* ctx) {
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
int coctx_make(coctx_t* ctx, coctx_pfn_t pfn, const void* s, const void* s1) {
|
||||
// make room for coctx_param
|
||||
char* sp = ctx->ss_sp + ctx->ss_size - sizeof(coctx_param_t);
|
||||
sp = (char*)((unsigned long)sp & -16L);
|
||||
|
||||
coctx_param_t* param = (coctx_param_t*)sp;
|
||||
void** ret_addr = (void**)(sp - sizeof(void*) * 2);
|
||||
*ret_addr = (void*)pfn;
|
||||
param->s1 = s;
|
||||
param->s2 = s1;
|
||||
|
||||
memset(ctx->regs, 0, sizeof(ctx->regs));
|
||||
|
||||
ctx->regs[kESP] = (char*)(sp) - sizeof(void*) * 2;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(__x86_64__)
|
||||
int coctx_make(coctx_t* ctx, coctx_pfn_t pfn, const void* s, const void* s1) {
|
||||
char* sp = ctx->ss_sp + ctx->ss_size - sizeof(void*);
|
||||
sp = (char*)((unsigned long)sp & -16LL);
|
||||
|
||||
memset(ctx->regs, 0, sizeof(ctx->regs));
|
||||
void** ret_addr = (void**)(sp);
|
||||
*ret_addr = (void*)pfn;
|
||||
|
||||
ctx->regs[kRSP] = sp;
|
||||
|
||||
ctx->regs[kRETAddr] = (char*)pfn;
|
||||
|
||||
ctx->regs[kRDI] = (char*)s;
|
||||
ctx->regs[kRSI] = (char*)s1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int coctx_init(coctx_t* ctx) {
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
42
trunk/3rdparty/libco/coctx.h
vendored
Normal file
42
trunk/3rdparty/libco/coctx.h
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CO_CTX_H__
|
||||
#define __CO_CTX_H__
|
||||
#include <stdlib.h>
|
||||
typedef void* (*coctx_pfn_t)( void* s, void* s2 );
|
||||
struct coctx_param_t
|
||||
{
|
||||
const void *s1;
|
||||
const void *s2;
|
||||
};
|
||||
struct coctx_t
|
||||
{
|
||||
#if defined(__i386__)
|
||||
void *regs[ 8 ];
|
||||
#else
|
||||
void *regs[ 14 ];
|
||||
#endif
|
||||
size_t ss_size;
|
||||
char *ss_sp;
|
||||
|
||||
};
|
||||
|
||||
int coctx_init( coctx_t *ctx );
|
||||
int coctx_make( coctx_t *ctx,coctx_pfn_t pfn,const void *s,const void *s1 );
|
||||
#endif
|
83
trunk/3rdparty/libco/coctx_swap.S
vendored
Normal file
83
trunk/3rdparty/libco/coctx_swap.S
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.globl coctx_swap
|
||||
#if !defined( __APPLE__ )
|
||||
.type coctx_swap, @function
|
||||
#endif
|
||||
coctx_swap:
|
||||
|
||||
#if defined(__i386__)
|
||||
movl 4(%esp), %eax
|
||||
movl %esp, 28(%eax)
|
||||
movl %ebp, 24(%eax)
|
||||
movl %esi, 20(%eax)
|
||||
movl %edi, 16(%eax)
|
||||
movl %edx, 12(%eax)
|
||||
movl %ecx, 8(%eax)
|
||||
movl %ebx, 4(%eax)
|
||||
|
||||
|
||||
movl 8(%esp), %eax
|
||||
movl 4(%eax), %ebx
|
||||
movl 8(%eax), %ecx
|
||||
movl 12(%eax), %edx
|
||||
movl 16(%eax), %edi
|
||||
movl 20(%eax), %esi
|
||||
movl 24(%eax), %ebp
|
||||
movl 28(%eax), %esp
|
||||
|
||||
ret
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
leaq (%rsp),%rax
|
||||
movq %rax, 104(%rdi)
|
||||
movq %rbx, 96(%rdi)
|
||||
movq %rcx, 88(%rdi)
|
||||
movq %rdx, 80(%rdi)
|
||||
movq 0(%rax), %rax
|
||||
movq %rax, 72(%rdi)
|
||||
movq %rsi, 64(%rdi)
|
||||
movq %rdi, 56(%rdi)
|
||||
movq %rbp, 48(%rdi)
|
||||
movq %r8, 40(%rdi)
|
||||
movq %r9, 32(%rdi)
|
||||
movq %r12, 24(%rdi)
|
||||
movq %r13, 16(%rdi)
|
||||
movq %r14, 8(%rdi)
|
||||
movq %r15, (%rdi)
|
||||
xorq %rax, %rax
|
||||
|
||||
movq 48(%rsi), %rbp
|
||||
movq 104(%rsi), %rsp
|
||||
movq (%rsi), %r15
|
||||
movq 8(%rsi), %r14
|
||||
movq 16(%rsi), %r13
|
||||
movq 24(%rsi), %r12
|
||||
movq 32(%rsi), %r9
|
||||
movq 40(%rsi), %r8
|
||||
movq 56(%rsi), %rdi
|
||||
movq 80(%rsi), %rdx
|
||||
movq 88(%rsi), %rcx
|
||||
movq 96(%rsi), %rbx
|
||||
leaq 8(%rsp), %rsp
|
||||
pushq 72(%rsi)
|
||||
|
||||
movq 64(%rsi), %rsi
|
||||
ret
|
||||
#endif
|
91
trunk/3rdparty/libco/example_closure.cpp
vendored
Normal file
91
trunk/3rdparty/libco/example_closure.cpp
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "co_closure.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
using namespace std;
|
||||
|
||||
static void *thread_func( void * arg )
|
||||
{
|
||||
stCoClosure_t *p = (stCoClosure_t*) arg;
|
||||
p->exec();
|
||||
return 0;
|
||||
}
|
||||
static void batch_exec( vector<stCoClosure_t*> &v )
|
||||
{
|
||||
vector<pthread_t> ths;
|
||||
for( size_t i=0;i<v.size();i++ )
|
||||
{
|
||||
pthread_t tid;
|
||||
pthread_create( &tid,0,thread_func,v[i] );
|
||||
ths.push_back( tid );
|
||||
}
|
||||
for( size_t i=0;i<v.size();i++ )
|
||||
{
|
||||
pthread_join( ths[i],0 );
|
||||
}
|
||||
}
|
||||
int main( int argc,char *argv[] )
|
||||
{
|
||||
vector< stCoClosure_t* > v;
|
||||
|
||||
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int total = 100;
|
||||
vector<int> v2;
|
||||
co_ref( ref,total,v2,m);
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
co_func( f,ref,i )
|
||||
{
|
||||
printf("ref.total %d i %d\n",ref.total,i );
|
||||
//lock
|
||||
pthread_mutex_lock(&ref.m);
|
||||
ref.v2.push_back( i );
|
||||
pthread_mutex_unlock(&ref.m);
|
||||
//unlock
|
||||
}
|
||||
co_func_end;
|
||||
v.push_back( new f( ref,i ) );
|
||||
}
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
co_func( f2,i )
|
||||
{
|
||||
printf("i: %d\n",i);
|
||||
for(int j=0;j<2;j++)
|
||||
{
|
||||
usleep( 1000 );
|
||||
printf("i %d j %d\n",i,j);
|
||||
}
|
||||
}
|
||||
co_func_end;
|
||||
v.push_back( new f2( i ) );
|
||||
}
|
||||
|
||||
batch_exec( v );
|
||||
printf("done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
83
trunk/3rdparty/libco/example_cond.cpp
vendored
Normal file
83
trunk/3rdparty/libco/example_cond.cpp
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <queue>
|
||||
#include "co_routine.h"
|
||||
using namespace std;
|
||||
struct stTask_t
|
||||
{
|
||||
int id;
|
||||
};
|
||||
struct stEnv_t
|
||||
{
|
||||
stCoCond_t* cond;
|
||||
queue<stTask_t*> task_queue;
|
||||
};
|
||||
void* Producer(void* args)
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
stEnv_t* env= (stEnv_t*)args;
|
||||
int id = 0;
|
||||
while (true)
|
||||
{
|
||||
stTask_t* task = (stTask_t*)calloc(1, sizeof(stTask_t));
|
||||
task->id = id++;
|
||||
env->task_queue.push(task);
|
||||
printf("%s:%d produce task %d\n", __func__, __LINE__, task->id);
|
||||
co_cond_signal(env->cond);
|
||||
poll(NULL, 0, 1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void* Consumer(void* args)
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
stEnv_t* env = (stEnv_t*)args;
|
||||
while (true)
|
||||
{
|
||||
if (env->task_queue.empty())
|
||||
{
|
||||
co_cond_timedwait(env->cond, -1);
|
||||
continue;
|
||||
}
|
||||
stTask_t* task = env->task_queue.front();
|
||||
env->task_queue.pop();
|
||||
printf("%s:%d consume task %d\n", __func__, __LINE__, task->id);
|
||||
free(task);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
stEnv_t* env = new stEnv_t;
|
||||
env->cond = co_cond_alloc();
|
||||
|
||||
stCoRoutine_t* consumer_routine;
|
||||
co_create(&consumer_routine, NULL, Consumer, env);
|
||||
co_resume(consumer_routine);
|
||||
|
||||
stCoRoutine_t* producer_routine;
|
||||
co_create(&producer_routine, NULL, Producer, env);
|
||||
co_resume(producer_routine);
|
||||
|
||||
co_eventloop(co_get_epoll_ct(), NULL, NULL);
|
||||
return 0;
|
||||
}
|
61
trunk/3rdparty/libco/example_copystack.cpp
vendored
Normal file
61
trunk/3rdparty/libco/example_copystack.cpp
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "coctx.h"
|
||||
#include "co_routine.h"
|
||||
#include "co_routine_inner.h"
|
||||
|
||||
void* RoutineFunc(void* args)
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
int* routineid = (int*)args;
|
||||
while (true)
|
||||
{
|
||||
char sBuff[128];
|
||||
sprintf(sBuff, "from routineid %d stack addr %p\n", *routineid, sBuff);
|
||||
|
||||
printf("%s", sBuff);
|
||||
poll(NULL, 0, 1000); //sleep 1s
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
stShareStack_t* share_stack= co_alloc_sharestack(1, 1024 * 128);
|
||||
stCoRoutineAttr_t attr;
|
||||
attr.stack_size = 0;
|
||||
attr.share_stack = share_stack;
|
||||
|
||||
stCoRoutine_t* co[2];
|
||||
int routineid[2];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
routineid[i] = i;
|
||||
co_create(&co[i], &attr, RoutineFunc, routineid + i);
|
||||
co_resume(co[i]);
|
||||
}
|
||||
co_eventloop(co_get_epoll_ct(), NULL, NULL);
|
||||
return 0;
|
||||
}
|
218
trunk/3rdparty/libco/example_echocli.cpp
vendored
Normal file
218
trunk/3rdparty/libco/example_echocli.cpp
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "co_routine.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <stack>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
using namespace std;
|
||||
struct stEndPoint
|
||||
{
|
||||
char *ip;
|
||||
unsigned short int port;
|
||||
};
|
||||
|
||||
static void SetAddr(const char *pszIP,const unsigned short shPort,struct sockaddr_in &addr)
|
||||
{
|
||||
bzero(&addr,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(shPort);
|
||||
int nIP = 0;
|
||||
if( !pszIP || '\0' == *pszIP
|
||||
|| 0 == strcmp(pszIP,"0") || 0 == strcmp(pszIP,"0.0.0.0")
|
||||
|| 0 == strcmp(pszIP,"*")
|
||||
)
|
||||
{
|
||||
nIP = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
nIP = inet_addr(pszIP);
|
||||
}
|
||||
addr.sin_addr.s_addr = nIP;
|
||||
|
||||
}
|
||||
|
||||
static int iSuccCnt = 0;
|
||||
static int iFailCnt = 0;
|
||||
static int iTime = 0;
|
||||
|
||||
void AddSuccCnt()
|
||||
{
|
||||
int now = time(NULL);
|
||||
if (now >iTime)
|
||||
{
|
||||
printf("time %d Succ Cnt %d Fail Cnt %d\n", iTime, iSuccCnt, iFailCnt);
|
||||
iTime = now;
|
||||
iSuccCnt = 0;
|
||||
iFailCnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSuccCnt++;
|
||||
}
|
||||
}
|
||||
void AddFailCnt()
|
||||
{
|
||||
int now = time(NULL);
|
||||
if (now >iTime)
|
||||
{
|
||||
printf("time %d Succ Cnt %d Fail Cnt %d\n", iTime, iSuccCnt, iFailCnt);
|
||||
iTime = now;
|
||||
iSuccCnt = 0;
|
||||
iFailCnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iFailCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
static void *readwrite_routine( void *arg )
|
||||
{
|
||||
|
||||
co_enable_hook_sys();
|
||||
|
||||
stEndPoint *endpoint = (stEndPoint *)arg;
|
||||
char str[8]="sarlmol";
|
||||
char buf[ 1024 * 16 ];
|
||||
int fd = -1;
|
||||
int ret = 0;
|
||||
for(;;)
|
||||
{
|
||||
if ( fd < 0 )
|
||||
{
|
||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||
struct sockaddr_in addr;
|
||||
SetAddr(endpoint->ip, endpoint->port, addr);
|
||||
ret = connect(fd,(struct sockaddr*)&addr,sizeof(addr));
|
||||
|
||||
if ( errno == EALREADY || errno == EINPROGRESS )
|
||||
{
|
||||
struct pollfd pf = { 0 };
|
||||
pf.fd = fd;
|
||||
pf.events = (POLLOUT|POLLERR|POLLHUP);
|
||||
co_poll( co_get_epoll_ct(),&pf,1,200);
|
||||
//check connect
|
||||
int error = 0;
|
||||
uint32_t socklen = sizeof(error);
|
||||
errno = 0;
|
||||
ret = getsockopt(fd, SOL_SOCKET, SO_ERROR,(void *)&error, &socklen);
|
||||
if ( ret == -1 )
|
||||
{
|
||||
//printf("getsockopt ERROR ret %d %d:%s\n", ret, errno, strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
AddFailCnt();
|
||||
continue;
|
||||
}
|
||||
if ( error )
|
||||
{
|
||||
errno = error;
|
||||
//printf("connect ERROR ret %d %d:%s\n", error, errno, strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
AddFailCnt();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ret = write( fd,str, 8);
|
||||
if ( ret > 0 )
|
||||
{
|
||||
ret = read( fd,buf, sizeof(buf) );
|
||||
if ( ret <= 0 )
|
||||
{
|
||||
//printf("co %p read ret %d errno %d (%s)\n",
|
||||
// co_self(), ret,errno,strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
AddFailCnt();
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("echo %s fd %d\n", buf,fd);
|
||||
AddSuccCnt();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("co %p write ret %d errno %d (%s)\n",
|
||||
// co_self(), ret,errno,strerror(errno));
|
||||
close(fd);
|
||||
fd = -1;
|
||||
AddFailCnt();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
stEndPoint endpoint;
|
||||
endpoint.ip = argv[1];
|
||||
endpoint.port = atoi(argv[2]);
|
||||
int cnt = atoi( argv[3] );
|
||||
int proccnt = atoi( argv[4] );
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction( SIGPIPE, &sa, NULL );
|
||||
|
||||
for(int k=0;k<proccnt;k++)
|
||||
{
|
||||
|
||||
pid_t pid = fork();
|
||||
if( pid > 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
for(int i=0;i<cnt;i++)
|
||||
{
|
||||
stCoRoutine_t *co = 0;
|
||||
co_create( &co,NULL,readwrite_routine, &endpoint);
|
||||
co_resume( co );
|
||||
}
|
||||
co_eventloop( co_get_epoll_ct(),0,0 );
|
||||
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*./example_echosvr 127.0.0.1 10000 100 50*/
|
255
trunk/3rdparty/libco/example_echosvr.cpp
vendored
Normal file
255
trunk/3rdparty/libco/example_echosvr.cpp
vendored
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "co_routine.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <stack>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <cstring>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
struct task_t
|
||||
{
|
||||
stCoRoutine_t *co;
|
||||
int fd;
|
||||
};
|
||||
|
||||
static stack<task_t*> g_readwrite;
|
||||
static int g_listen_fd = -1;
|
||||
static int SetNonBlock(int iSock)
|
||||
{
|
||||
int iFlags;
|
||||
|
||||
iFlags = fcntl(iSock, F_GETFL, 0);
|
||||
iFlags |= O_NONBLOCK;
|
||||
iFlags |= O_NDELAY;
|
||||
int ret = fcntl(iSock, F_SETFL, iFlags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *readwrite_routine( void *arg )
|
||||
{
|
||||
|
||||
co_enable_hook_sys();
|
||||
|
||||
task_t *co = (task_t*)arg;
|
||||
char buf[ 1024 * 16 ];
|
||||
for(;;)
|
||||
{
|
||||
if( -1 == co->fd )
|
||||
{
|
||||
g_readwrite.push( co );
|
||||
co_yield_ct();
|
||||
continue;
|
||||
}
|
||||
|
||||
int fd = co->fd;
|
||||
co->fd = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
struct pollfd pf = { 0 };
|
||||
pf.fd = fd;
|
||||
pf.events = (POLLIN|POLLERR|POLLHUP);
|
||||
co_poll( co_get_epoll_ct(),&pf,1,1000);
|
||||
|
||||
int ret = read( fd,buf,sizeof(buf) );
|
||||
if( ret > 0 )
|
||||
{
|
||||
ret = write( fd,buf,ret );
|
||||
}
|
||||
if( ret > 0 || ( -1 == ret && EAGAIN == errno ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
close( fd );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int co_accept(int fd, struct sockaddr *addr, socklen_t *len );
|
||||
static void *accept_routine( void * )
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
printf("accept_routine\n");
|
||||
fflush(stdout);
|
||||
for(;;)
|
||||
{
|
||||
//printf("pid %ld g_readwrite.size %ld\n",getpid(),g_readwrite.size());
|
||||
if( g_readwrite.empty() )
|
||||
{
|
||||
printf("empty\n"); //sleep
|
||||
struct pollfd pf = { 0 };
|
||||
pf.fd = -1;
|
||||
poll( &pf,1,1000);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
struct sockaddr_in addr; //maybe sockaddr_un;
|
||||
memset( &addr,0,sizeof(addr) );
|
||||
socklen_t len = sizeof(addr);
|
||||
|
||||
int fd = co_accept(g_listen_fd, (struct sockaddr *)&addr, &len);
|
||||
if( fd < 0 )
|
||||
{
|
||||
struct pollfd pf = { 0 };
|
||||
pf.fd = g_listen_fd;
|
||||
pf.events = (POLLIN|POLLERR|POLLHUP);
|
||||
co_poll( co_get_epoll_ct(),&pf,1,1000 );
|
||||
continue;
|
||||
}
|
||||
if( g_readwrite.empty() )
|
||||
{
|
||||
close( fd );
|
||||
continue;
|
||||
}
|
||||
SetNonBlock( fd );
|
||||
task_t *co = g_readwrite.top();
|
||||
co->fd = fd;
|
||||
g_readwrite.pop();
|
||||
co_resume( co->co );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SetAddr(const char *pszIP,const unsigned short shPort,struct sockaddr_in &addr)
|
||||
{
|
||||
bzero(&addr,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(shPort);
|
||||
int nIP = 0;
|
||||
if( !pszIP || '\0' == *pszIP
|
||||
|| 0 == strcmp(pszIP,"0") || 0 == strcmp(pszIP,"0.0.0.0")
|
||||
|| 0 == strcmp(pszIP,"*")
|
||||
)
|
||||
{
|
||||
nIP = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
nIP = inet_addr(pszIP);
|
||||
}
|
||||
addr.sin_addr.s_addr = nIP;
|
||||
|
||||
}
|
||||
|
||||
static int CreateTcpSocket(const unsigned short shPort /* = 0 */,const char *pszIP /* = "*" */,bool bReuse /* = false */)
|
||||
{
|
||||
int fd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
|
||||
if( fd >= 0 )
|
||||
{
|
||||
if(shPort != 0)
|
||||
{
|
||||
if(bReuse)
|
||||
{
|
||||
int nReuseAddr = 1;
|
||||
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&nReuseAddr,sizeof(nReuseAddr));
|
||||
}
|
||||
struct sockaddr_in addr ;
|
||||
SetAddr(pszIP,shPort,addr);
|
||||
int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
|
||||
if( ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
if(argc<5){
|
||||
printf("Usage:\n"
|
||||
"example_echosvr [IP] [PORT] [TASK_COUNT] [PROCESS_COUNT]\n"
|
||||
"example_echosvr [IP] [PORT] [TASK_COUNT] [PROCESS_COUNT] -d # daemonize mode\n");
|
||||
return -1;
|
||||
}
|
||||
const char *ip = argv[1];
|
||||
int port = atoi( argv[2] );
|
||||
int cnt = atoi( argv[3] );
|
||||
int proccnt = atoi( argv[4] );
|
||||
bool deamonize = argc >= 6 && strcmp(argv[5], "-d") == 0;
|
||||
|
||||
g_listen_fd = CreateTcpSocket( port,ip,true );
|
||||
listen( g_listen_fd,1024 );
|
||||
if(g_listen_fd==-1){
|
||||
printf("Port %d is in use\n", port);
|
||||
return -1;
|
||||
}
|
||||
printf("listen %d %s:%d\n",g_listen_fd,ip,port);
|
||||
|
||||
SetNonBlock( g_listen_fd );
|
||||
|
||||
for(int k=0;k<proccnt;k++)
|
||||
{
|
||||
|
||||
pid_t pid = fork();
|
||||
if( pid > 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if( pid < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
for(int i=0;i<cnt;i++)
|
||||
{
|
||||
task_t * task = (task_t*)calloc( 1,sizeof(task_t) );
|
||||
task->fd = -1;
|
||||
|
||||
co_create( &(task->co),NULL,readwrite_routine,task );
|
||||
co_resume( task->co );
|
||||
|
||||
}
|
||||
stCoRoutine_t *accept_co = NULL;
|
||||
co_create( &accept_co,NULL,accept_routine,0 );
|
||||
co_resume( accept_co );
|
||||
|
||||
co_eventloop( co_get_epoll_ct(),0,0 );
|
||||
|
||||
exit(0);
|
||||
}
|
||||
if(!deamonize) wait(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
211
trunk/3rdparty/libco/example_poll.cpp
vendored
Normal file
211
trunk/3rdparty/libco/example_poll.cpp
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "co_routine.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <stack>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct task_t
|
||||
{
|
||||
stCoRoutine_t *co;
|
||||
int fd;
|
||||
struct sockaddr_in addr;
|
||||
};
|
||||
|
||||
static int SetNonBlock(int iSock)
|
||||
{
|
||||
int iFlags;
|
||||
|
||||
iFlags = fcntl(iSock, F_GETFL, 0);
|
||||
iFlags |= O_NONBLOCK;
|
||||
iFlags |= O_NDELAY;
|
||||
int ret = fcntl(iSock, F_SETFL, iFlags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SetAddr(const char *pszIP,const unsigned short shPort,struct sockaddr_in &addr)
|
||||
{
|
||||
bzero(&addr,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(shPort);
|
||||
int nIP = 0;
|
||||
if( !pszIP || '\0' == *pszIP
|
||||
|| 0 == strcmp(pszIP,"0") || 0 == strcmp(pszIP,"0.0.0.0")
|
||||
|| 0 == strcmp(pszIP,"*")
|
||||
)
|
||||
{
|
||||
nIP = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
nIP = inet_addr(pszIP);
|
||||
}
|
||||
addr.sin_addr.s_addr = nIP;
|
||||
|
||||
}
|
||||
|
||||
static int CreateTcpSocket(const unsigned short shPort = 0 ,const char *pszIP = "*" ,bool bReuse = false )
|
||||
{
|
||||
int fd = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
|
||||
if( fd >= 0 )
|
||||
{
|
||||
if(shPort != 0)
|
||||
{
|
||||
if(bReuse)
|
||||
{
|
||||
int nReuseAddr = 1;
|
||||
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&nReuseAddr,sizeof(nReuseAddr));
|
||||
}
|
||||
struct sockaddr_in addr ;
|
||||
SetAddr(pszIP,shPort,addr);
|
||||
int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
|
||||
if( ret != 0)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void *poll_routine( void *arg )
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
|
||||
vector<task_t> &v = *(vector<task_t>*)arg;
|
||||
for(size_t i=0;i<v.size();i++)
|
||||
{
|
||||
int fd = CreateTcpSocket();
|
||||
SetNonBlock( fd );
|
||||
v[i].fd = fd;
|
||||
|
||||
int ret = connect(fd,(struct sockaddr*)&v[i].addr,sizeof( v[i].addr ));
|
||||
printf("co %p connect i %ld ret %d errno %d (%s)\n",
|
||||
co_self(),i,ret,errno,strerror(errno));
|
||||
}
|
||||
struct pollfd *pf = (struct pollfd*)calloc( 1,sizeof(struct pollfd) * v.size() );
|
||||
|
||||
for(size_t i=0;i<v.size();i++)
|
||||
{
|
||||
pf[i].fd = v[i].fd;
|
||||
pf[i].events = ( POLLOUT | POLLERR | POLLHUP );
|
||||
}
|
||||
set<int> setRaiseFds;
|
||||
size_t iWaitCnt = v.size();
|
||||
for(;;)
|
||||
{
|
||||
int ret = poll( pf,iWaitCnt,1000 );
|
||||
printf("co %p poll wait %ld ret %d\n",
|
||||
co_self(),iWaitCnt,ret);
|
||||
for(int i=0;i<(int)iWaitCnt;i++)
|
||||
{
|
||||
printf("co %p fire fd %d revents 0x%X POLLOUT 0x%X POLLERR 0x%X POLLHUP 0x%X\n",
|
||||
co_self(),
|
||||
pf[i].fd,
|
||||
pf[i].revents,
|
||||
POLLOUT,
|
||||
POLLERR,
|
||||
POLLHUP
|
||||
);
|
||||
setRaiseFds.insert( pf[i].fd );
|
||||
}
|
||||
if( setRaiseFds.size() == v.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
if( ret <= 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
iWaitCnt = 0;
|
||||
for(size_t i=0;i<v.size();i++)
|
||||
{
|
||||
if( setRaiseFds.find( v[i].fd ) == setRaiseFds.end() )
|
||||
{
|
||||
pf[ iWaitCnt ].fd = v[i].fd;
|
||||
pf[ iWaitCnt ].events = ( POLLOUT | POLLERR | POLLHUP );
|
||||
++iWaitCnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(size_t i=0;i<v.size();i++)
|
||||
{
|
||||
close( v[i].fd );
|
||||
v[i].fd = -1;
|
||||
}
|
||||
|
||||
printf("co %p task cnt %ld fire %ld\n",
|
||||
co_self(),v.size(),setRaiseFds.size() );
|
||||
return 0;
|
||||
}
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
vector<task_t> v;
|
||||
for(int i=1;i<argc;i+=2)
|
||||
{
|
||||
task_t task = { 0 };
|
||||
SetAddr( argv[i],atoi(argv[i+1]),task.addr );
|
||||
v.push_back( task );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
printf("--------------------- main -------------------\n");
|
||||
vector<task_t> v2 = v;
|
||||
poll_routine( &v2 );
|
||||
printf("--------------------- routine -------------------\n");
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
stCoRoutine_t *co = 0;
|
||||
vector<task_t> *v2 = new vector<task_t>();
|
||||
*v2 = v;
|
||||
co_create( &co,NULL,poll_routine,v2 );
|
||||
printf("routine i %d\n",i);
|
||||
co_resume( co );
|
||||
}
|
||||
|
||||
co_eventloop( co_get_epoll_ct(),0,0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
//./example_poll 127.0.0.1 12365 127.0.0.1 12222 192.168.1.1 1000 192.168.1.2 1111
|
||||
|
89
trunk/3rdparty/libco/example_setenv.cpp
vendored
Normal file
89
trunk/3rdparty/libco/example_setenv.cpp
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <queue>
|
||||
#include "co_routine.h"
|
||||
|
||||
const char* CGI_ENV_HOOK_LIST [] =
|
||||
{
|
||||
"CGINAME",
|
||||
};
|
||||
struct stRoutineArgs_t
|
||||
{
|
||||
int iRoutineID;
|
||||
};
|
||||
void SetAndGetEnv(int iRoutineID)
|
||||
{
|
||||
printf("routineid %d begin\n", iRoutineID);
|
||||
|
||||
//use poll as sleep
|
||||
poll(NULL, 0, 500);
|
||||
|
||||
char sBuf[128];
|
||||
sprintf(sBuf, "cgi_routine_%d", iRoutineID);
|
||||
int ret = setenv("CGINAME", sBuf, 1);
|
||||
if (ret)
|
||||
{
|
||||
printf("%s:%d set env err ret %d errno %d %s\n", __func__, __LINE__,
|
||||
ret, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
printf("routineid %d set env CGINAME %s\n", iRoutineID, sBuf);
|
||||
|
||||
poll(NULL, 0, 500);
|
||||
|
||||
char* env = getenv("CGINAME");
|
||||
if (!env)
|
||||
{
|
||||
printf("%s:%d get env err errno %d %s\n", __func__, __LINE__,
|
||||
errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
printf("routineid %d get env CGINAME %s\n", iRoutineID, env);
|
||||
}
|
||||
|
||||
void* RoutineFunc(void* args)
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
|
||||
stRoutineArgs_t* g = (stRoutineArgs_t*)args;
|
||||
|
||||
SetAndGetEnv(g->iRoutineID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
co_set_env_list(CGI_ENV_HOOK_LIST, sizeof(CGI_ENV_HOOK_LIST) / sizeof(char*));
|
||||
stRoutineArgs_t args[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
stCoRoutine_t* co = NULL;
|
||||
args[i].iRoutineID = i;
|
||||
co_create(&co, NULL, RoutineFunc, &args[i]);
|
||||
co_resume(co);
|
||||
}
|
||||
co_eventloop(co_get_epoll_ct(), NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
61
trunk/3rdparty/libco/example_specific.cpp
vendored
Normal file
61
trunk/3rdparty/libco/example_specific.cpp
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "co_routine_specific.h"
|
||||
#include "co_routine.h"
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
struct stRoutineArgs_t
|
||||
{
|
||||
stCoRoutine_t* co;
|
||||
int routine_id;
|
||||
};
|
||||
struct stRoutineSpecificData_t
|
||||
{
|
||||
int idx;
|
||||
};
|
||||
|
||||
CO_ROUTINE_SPECIFIC(stRoutineSpecificData_t, __routine);
|
||||
|
||||
void* RoutineFunc(void* args)
|
||||
{
|
||||
co_enable_hook_sys();
|
||||
stRoutineArgs_t* routine_args = (stRoutineArgs_t*)args;
|
||||
__routine->idx = routine_args->routine_id;
|
||||
while (true)
|
||||
{
|
||||
printf("%s:%d routine specific data idx %d\n", __func__, __LINE__, __routine->idx);
|
||||
poll(NULL, 0, 1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
stRoutineArgs_t args[10];
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
args[i].routine_id = i;
|
||||
co_create(&args[i].co, NULL, RoutineFunc, (void*)&args[i]);
|
||||
co_resume(args[i].co);
|
||||
}
|
||||
co_eventloop(co_get_epoll_ct(), NULL, NULL);
|
||||
return 0;
|
||||
}
|
56
trunk/3rdparty/libco/example_thread.cpp
vendored
Normal file
56
trunk/3rdparty/libco/example_thread.cpp
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Tencent is pleased to support the open source community by making Libco available.
|
||||
|
||||
* Copyright (C) 2014 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "co_routine.h"
|
||||
#include "co_routine_inner.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int loop(void *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void *routine_func( void * )
|
||||
{
|
||||
stCoEpoll_t * ev = co_get_epoll_ct(); //ct = current thread
|
||||
co_eventloop( ev,loop,0 );
|
||||
return 0;
|
||||
}
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int cnt = atoi( argv[1] );
|
||||
|
||||
pthread_t tid[ cnt ];
|
||||
for(int i=0;i<cnt;i++)
|
||||
{
|
||||
pthread_create( tid + i,NULL,routine_func,0);
|
||||
}
|
||||
for(;;)
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue