diff --git a/lib_fiber/c/include/fiber/fiber_mutex.h b/lib_fiber/c/include/fiber/fiber_mutex.h index ac17f3687..233d30d35 100644 --- a/lib_fiber/c/include/fiber/fiber_mutex.h +++ b/lib_fiber/c/include/fiber/fiber_mutex.h @@ -32,7 +32,7 @@ typedef struct ACL_FIBER_MUTEX_STATS { FIBER_API void acl_fiber_mutex_profile(void); -FIBER_API ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadcheck(void); +FIBER_API ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadlock(void); FIBER_API void acl_fiber_mutex_stats_free(ACL_FIBER_MUTEX_STATS *stats); FIBER_API void acl_fiber_mutex_stats_show(const ACL_FIBER_MUTEX_STATS *stats); diff --git a/lib_fiber/c/src/sync/fiber_mutex.c b/lib_fiber/c/src/sync/fiber_mutex.c index 8bda83fe1..26c96ecac 100644 --- a/lib_fiber/c/src/sync/fiber_mutex.c +++ b/lib_fiber/c/src/sync/fiber_mutex.c @@ -259,7 +259,6 @@ static ACL_FIBER_MUTEX_STATS *check_deadlock2(MUTEX_CHECK *check) SNPRINTF(hkey, sizeof(hkey), "%d", acl_fiber_id(fiber)); if (htable_find(table, hkey) != NULL) { deadlocked = 1; - printf("DeadLock happened!\r\n"); break; } } @@ -314,7 +313,7 @@ static ACL_FIBER_MUTEX_STATS *check_deadlock(THREAD_MUTEXES *mutexes) return stats; } -ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadcheck(void) +ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadlock(void) { if (__locks != NULL) { ACL_FIBER_MUTEX_STATS *stats; diff --git a/lib_fiber/cpp/include/fiber/fiber.hpp b/lib_fiber/cpp/include/fiber/fiber.hpp index 55de434a6..653c45233 100644 --- a/lib_fiber/cpp/include/fiber/fiber.hpp +++ b/lib_fiber/cpp/include/fiber/fiber.hpp @@ -17,9 +17,8 @@ typedef enum FIBER_EVENT_T_IO_URING, // Linux } fiber_event_t; -class FIBER_CPP_API fiber_frame +struct FIBER_CPP_API fiber_frame { -public: fiber_frame(void) : pc(0), off(0) {} ~fiber_frame(void) {} @@ -34,6 +33,9 @@ public: class FIBER_CPP_API fiber { public: + fiber(void); + fiber(ACL_FIBER *fb); + /** * 构造函数 * @param running {bool} 当为 true 时,则表示当前协程已启动,仅是声明 @@ -41,7 +43,8 @@ public: * 象的 start 方法启动新协程; 当为 false 时,则需要调用 start 方法来 * 启动新协程 */ - fiber(bool running = false); + fiber(bool running); + virtual ~fiber(void); /** @@ -87,6 +90,12 @@ public: */ static unsigned int self(void); + /** + * 获得指定协程对象的ID号 + * @return {unsigned int} + */ + static unsigned int id(const fiber& fb); + /** * 获得当前协程在执行某个系统 API 出错时的错误号 * return {int} diff --git a/lib_fiber/cpp/include/fiber/fiber_mutex.hpp b/lib_fiber/cpp/include/fiber/fiber_mutex.hpp index 1f0375d6f..c529264d6 100644 --- a/lib_fiber/cpp/include/fiber/fiber_mutex.hpp +++ b/lib_fiber/cpp/include/fiber/fiber_mutex.hpp @@ -1,5 +1,7 @@ #pragma once +#include #include "fiber_cpp_define.hpp" +#include "fiber_mutex_stat.hpp" struct ACL_FIBER_MUTEX; @@ -12,7 +14,13 @@ namespace acl { class FIBER_CPP_API fiber_mutex { public: - fiber_mutex(void); + /** + * 构造函数 + * @param mutex {ACL_FIBER_MUTEX*} 非空时,将用 C 的锁对象创建 C++ 锁 + * 对象,否则内部自动创建 C 锁对象;如果非空时,在本对象析构时该传入的 + * C 锁对象需由应用层自行释放. + */ + fiber_mutex(ACL_FIBER_MUTEX* mutex = NULL); ~fiber_mutex(void); /** @@ -43,8 +51,16 @@ public: return mutex_; } + /** + * 进行全局死锁检测 + * @param out {fiber_mutex_stats&} 存储结果集 + * @return {bool} 返回 true 表示存在死锁问题, 死锁信息存放在 out 中 + */ + static bool deadlock(fiber_mutex_stats& out); + private: ACL_FIBER_MUTEX* mutex_; + ACL_FIBER_MUTEX* mutex_internal_; fiber_mutex(const fiber_mutex&); void operator=(const fiber_mutex&); diff --git a/lib_fiber/cpp/include/fiber/fiber_mutex_stat.hpp b/lib_fiber/cpp/include/fiber/fiber_mutex_stat.hpp new file mode 100644 index 000000000..be4aae39e --- /dev/null +++ b/lib_fiber/cpp/include/fiber/fiber_mutex_stat.hpp @@ -0,0 +1,27 @@ +#pragma once + +struct ACL_FIBER_MUTEX; + +namespace acl { + +class fiber; + +struct FIBER_CPP_API fiber_mutex_stat +{ + fiber_mutex_stat(void) : fb(NULL), waiting(NULL) {} + ~fiber_mutex_stat(void) {} + + fiber *fb; + ACL_FIBER_MUTEX *waiting; + std::vector holding; +}; + +struct FIBER_CPP_API fiber_mutex_stats +{ + fiber_mutex_stats(void) {} + ~fiber_mutex_stats(void); + + std::vector stats; +}; + +} // namespace acl diff --git a/lib_fiber/cpp/include/fiber/libfiber.hpp b/lib_fiber/cpp/include/fiber/libfiber.hpp index 263c77f01..cb9a326a0 100644 --- a/lib_fiber/cpp/include/fiber/libfiber.hpp +++ b/lib_fiber/cpp/include/fiber/libfiber.hpp @@ -4,6 +4,8 @@ #include "fiber_lock.hpp" #include "fiber_event.hpp" +#include "fiber_mutex.hpp" +#include "fiber_mutex_stat.hpp" #include "fiber_cond.hpp" #include "wait_group.hpp" #include "fiber_sem.hpp" diff --git a/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj b/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj index 1a68ad882..af51e792b 100644 --- a/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj +++ b/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj @@ -315,6 +315,8 @@ + + @@ -331,6 +333,8 @@ + + diff --git a/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj.filters b/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj.filters index 75053628b..7fe1b3fef 100644 --- a/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj.filters +++ b/lib_fiber/cpp/libfiber_cpp_vc2012.vcxproj.filters @@ -45,6 +45,12 @@ 澶存枃浠 + + 澶存枃浠 + + + 澶存枃浠 + 澶存枃浠 @@ -83,6 +89,12 @@ 婧愭枃浠 + + 婧愭枃浠 + + + 婧愭枃浠 + 婧愭枃浠 diff --git a/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj b/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj index b132015f9..324cbe069 100644 --- a/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj +++ b/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj @@ -309,6 +309,8 @@ + + @@ -325,6 +327,8 @@ + + diff --git a/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj.filters b/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj.filters index 0bce6ea9f..915049530 100644 --- a/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj.filters +++ b/lib_fiber/cpp/libfiber_cpp_vc2013.vcxproj.filters @@ -36,6 +36,12 @@ 婧愭枃浠 + + 婧愭枃浠 + + + 婧愭枃浠 + 婧愭枃浠 @@ -74,6 +80,12 @@ 澶存枃浠 + + 澶存枃浠 + + + 澶存枃浠 + 澶存枃浠 diff --git a/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj b/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj index 39cf27de8..e78b55fed 100644 --- a/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj +++ b/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj @@ -316,6 +316,7 @@ + @@ -345,6 +346,7 @@ + diff --git a/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj.filters b/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj.filters index 20c7bbca2..0a2299a71 100644 --- a/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj.filters +++ b/lib_fiber/cpp/libfiber_cpp_vc2019.vcxproj.filters @@ -75,6 +75,9 @@ 婧愭枃浠 + + 婧愭枃浠 + 婧愭枃浠 @@ -140,6 +143,9 @@ 澶存枃浠 + + 澶存枃浠 + 澶存枃浠 diff --git a/lib_fiber/cpp/src/fiber.cpp b/lib_fiber/cpp/src/fiber.cpp index 7080d69a1..4640cdbc7 100644 --- a/lib_fiber/cpp/src/fiber.cpp +++ b/lib_fiber/cpp/src/fiber.cpp @@ -4,7 +4,17 @@ namespace acl { -fiber::fiber(bool running /* = false */) +fiber::fiber(void) +{ + f_ = NULL; +} + +fiber::fiber(ACL_FIBER *f) +{ + f_ = f; +} + +fiber::fiber(bool running) { if (running) { f_ = acl_fiber_running(); @@ -31,6 +41,12 @@ unsigned int fiber::self(void) return acl_fiber_self(); } +unsigned int fiber::id(const fiber& fb) +{ + ACL_FIBER *f = fb.get_fiber(); + return f ? acl_fiber_id(f) : 0; +} + int fiber::get_errno(void) const { return f_ ? acl_fiber_errno(f_) : -1; diff --git a/lib_fiber/cpp/src/fiber_mutex.cpp b/lib_fiber/cpp/src/fiber_mutex.cpp index a57766509..6d2fb4f12 100644 --- a/lib_fiber/cpp/src/fiber_mutex.cpp +++ b/lib_fiber/cpp/src/fiber_mutex.cpp @@ -1,16 +1,24 @@ #include "stdafx.hpp" +#include "fiber/fiber.hpp" #include "fiber/fiber_mutex.hpp" namespace acl { -fiber_mutex::fiber_mutex(void) +fiber_mutex::fiber_mutex(ACL_FIBER_MUTEX *mutex /* NULL */) { - mutex_ = acl_fiber_mutex_create(0); + if (mutex) { + mutex_ = mutex; + mutex_internal_ = NULL; + } else { + mutex_internal_ = mutex_ = acl_fiber_mutex_create(0); + } } fiber_mutex::~fiber_mutex(void) { - acl_fiber_mutex_free(mutex_); + if (mutex_internal_) { + acl_fiber_mutex_free(mutex_internal_); + } } bool fiber_mutex::lock(void) @@ -30,4 +38,29 @@ bool fiber_mutex::unlock(void) return true; } +bool fiber_mutex::deadlock(fiber_mutex_stats& out) +{ + ACL_FIBER_MUTEX_STATS *stats = acl_fiber_mutex_deadlock(); + + if (stats == NULL) { + return false; + } + + for (size_t i = 0; i < stats->count; i++) { + fiber_mutex_stat stat; + stat.fb = new fiber(stats->stats[i].fiber); + stat.waiting = stats->stats[i].waiting; + + for (size_t j = 0; j < stats->stats[i].count; j++) { + ACL_FIBER_MUTEX* mutex = stats->stats[i].holding[j]; + stat.holding.push_back(mutex); + } + + out.stats.push_back(stat); + } + + acl_fiber_mutex_stats_free(stats); + return true; +} + } // namespace acl diff --git a/lib_fiber/cpp/src/fiber_mutex_stat.cpp b/lib_fiber/cpp/src/fiber_mutex_stat.cpp new file mode 100644 index 000000000..02e85a191 --- /dev/null +++ b/lib_fiber/cpp/src/fiber_mutex_stat.cpp @@ -0,0 +1,16 @@ +#include "stdafx.hpp" +#include "fiber/fiber.hpp" +#include "fiber/fiber_mutex.hpp" +#include "fiber/fiber_mutex_stat.hpp" + +namespace acl { + +fiber_mutex_stats::~fiber_mutex_stats(void) +{ + for (std::vector::iterator it = stats.begin(); + it != stats.end(); ++it) { + delete (*it).fb; + } +} + +} // namespace acl diff --git a/lib_fiber/samples/dead_lock/main.c b/lib_fiber/samples/dead_lock/main.c index a1f516dec..b2f312e12 100644 --- a/lib_fiber/samples/dead_lock/main.c +++ b/lib_fiber/samples/dead_lock/main.c @@ -65,7 +65,7 @@ static void fiber_check(ACL_FIBER *fb, void *ctx) sleep(1); printf("\r\n"); //acl_fiber_mutex_profile(); - stats = acl_fiber_mutex_deadcheck(); + stats = acl_fiber_mutex_deadlock(); if (stats) { acl_fiber_mutex_stats_show(stats); acl_fiber_mutex_stats_free(stats); diff --git a/lib_fiber/samples/dead_lock2/Makefile b/lib_fiber/samples/dead_lock2/Makefile new file mode 100644 index 000000000..e1138af39 --- /dev/null +++ b/lib_fiber/samples/dead_lock2/Makefile @@ -0,0 +1,6 @@ +# Don't build the sample on MacOS because libunwind don't support it. +include ./Makefile.in +ifeq ($(findstring Linux, $(UNIXNAME)), Linux) + SYSLIB += -lunwind -lunwind-x86_64 +endif +PROG = dead_lock diff --git a/lib_fiber/samples/dead_lock2/Makefile.in b/lib_fiber/samples/dead_lock2/Makefile.in new file mode 100644 index 000000000..9add55785 --- /dev/null +++ b/lib_fiber/samples/dead_lock2/Makefile.in @@ -0,0 +1,174 @@ +CC = g++ + +CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \ +-Wno-long-long -Wpointer-arith -Werror -Wshadow -O0 \ +-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO + +########################################################### +#Check system: +# Linux, SunOS, Solaris, BSD variants, AIX, HP-UX +SYSLIB = -ldl -lpthread -lz +CHECKSYSRES = @echo "Unknow system type!";exit 1 +UNIXNAME = $(shell uname -sm) +OSTYPE = $(shell uname -p) +RPATH = linux64 + +ifeq ($(CC),) + CC = g++ +endif + +OS_ENV=$(shell uname -a) +ifeq ($(findstring WSL, $(OS_ENV)), WSL) + SYSLIB += -liconv +endif + +ifeq ($(findstring ubuntu, $(OS_ENV)), ubuntu) + SYSLIB += -liconv +endif + +ifeq ($(findstring Alpine, $(shell uname -a)), Alpine) + SYSLIB += -lucontext +endif + +ifeq ($(findstring g++, $(CC)), g++) + GCC_VERSION:=$(shell echo `gcc --version|grep ^gcc|cut -d' ' -f3`) + GCC_MAJOR:=$(shell echo "$(GCC_VERSION)" | cut -d'.' -f1) + GCC_MINOR:=$(shell echo "$(GCC_VERSION)" | cut -d'.' -f2) + GCC_VER:=$(shell [ $(GCC_MAJOR) -gt 4 -o \( $(GCC_MAJOR) -eq 4 -a $(GCC_MINOR) -ge 7 \) ] && echo true) + ifeq ($(GCC_VER), true) + CFLAGS += -std=c++11 -DACL_USE_CPP11 + endif +endif + +# For FreeBSD +ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD) + ifeq ($(findstring gcc, $(CC)), gcc) + CFLAGS += -Wstrict-prototypes + endif + CFLAGS += -DFREEBSD -D_REENTRANT + SYSLIB = -lcrypt -lpthread -lz + RPATH = freebsd +endif + +# For Darwin +ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin) +# CC += -arch x86_64 -arch arm64 + CFLAGS += -DMACOSX -Wno-invalid-source-encoding \ + -Wno-invalid-offsetof + UNIXTYPE = MACOSX + SYSLIB += -liconv -rdynamic + RPATH = macos +endif + +#Path for Linux +ifeq ($(findstring Linux, $(UNIXNAME)), Linux) + ifeq ($CC, "gcc") + CFLAGS += -Wstrict-prototypes + endif + ifeq ($(findstring i686, $(OSTYPE)), i686) + RPATH = linux32 + endif + ifeq ($(findstring x86_64, $(OSTYPE)), x86_64) + RPATH = linux64 + endif + ifeq ($(HAS_IO_URING), yes) + SYSLIB += -luring + endif + ifeq ($(has_io_uring), yes) + SYSLIB += -luring + endif +# CFLAGS += -DLINUX2 -D_REENTRANT + CFLAGS += -D_REENTRANT + SYSLIB += -lcrypt +endif + +#Path for SunOS +ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS) + ifeq ($(findstring 86, $(UNIXNAME)), 86) + SYSLIB += -lsocket -lnsl -lrt + endif + ifeq ($(findstring sun4u, $(UNIXNAME)), sun4u) + SYSLIB += -lsocket -lnsl -lrt + endif + ifeq ($CC, "gcc") + CFLAGS += -Wstrict-prototypes + endif + CFLAGS += -DSUNOS5 -D_REENTRANT + RPATH = sunos_x86 +endif + +#Path for HP-UX +ifeq ($(findstring HP-UX, $(UNIXNAME)), HP-UX) + ifeq ($CC, "gcc") + CFLAGS += -Wstrict-prototypes + endif + CFLAGS += -DHP_UX -DHPUX11 + PLAT_NAME=hp-ux +endif + +# For CYGWIN +ifeq ($(findstring CYGWIN, $(UNIXNAME)), CYGWIN) + SYSLIB = -lpthread -rdynamic + CFLAGS += -DLINUX2 -DMINGW + UNIXTYPE = LINUX +endif + +# For MINGW +ifeq ($(findstring MINGW, $(UNIXNAME)), MINGW) + SYSLIB = -lpthread -rdynamic + CFLAGS += -DLINUX2 -DMINGW + UNIXTYPE = LINUX +endif + +# For MSYS +ifeq ($(findstring MSYS, $(UNIXNAME)), MSYS) + SYSLIB = -lpthread -rdynamic + CFLAGS += -DLINUX2 -DMINGW + UNIXTYPE = LINUX +endif + +#Find system type. +ifneq ($(SYSPATH),) + CHECKSYSRES = @echo "System is $(shell uname -sm)" +endif +########################################################### + +CFLAGS += -I.. -I../../../lib_acl/include -I../../../lib_protocol/include -I../../../lib_acl_cpp/include \ + -I../../../lib_fiber/c/include -I../../../lib_fiber/cpp/include +EXTLIBS = +LDFLAGS = -L../../../lib_fiber/lib -lfiber_cpp \ + -L../../../lib_acl_cpp/lib -lacl_cpp \ + -L../../../lib_protocol/lib -lprotocol \ + -L../../../lib_acl/lib -lacl \ + -lfiber $(EXTLIBS) $(SYSLIB) + +COMPILE = $(CC) $(CFLAGS) +LINK = $(CC) $(OBJ) $(LDFLAGS) +########################################################### +OBJ_PATH = . + +#Project's objs +SRC = $(wildcard *.cpp) +OBJ = $(patsubst %.cpp, $(OBJ_PATH)/%.o, $(notdir $(SRC))) + +$(OBJ_PATH)/%.o: %.cpp + $(COMPILE) $< -o $@ + +.PHONY = all clean +all: RM $(OBJ) + $(LINK) -o $(PROG) + @echo "" + @echo "All ok! Output:$(PROG)" + @echo "" +RM: + rm -f $(PROG) +clean cl: + rm -f $(PROG) + rm -f $(OBJ) + +rebuild rb: clean all + +install: + cp $(PROG) ../../../dist/master/libexec/$(RPATH)/ + cp $(PROG).cf ../../../dist/master/conf/service/ +########################################################### diff --git a/lib_fiber/samples/dead_lock2/main.cpp b/lib_fiber/samples/dead_lock2/main.cpp new file mode 100644 index 000000000..ea0237585 --- /dev/null +++ b/lib_fiber/samples/dead_lock2/main.cpp @@ -0,0 +1,152 @@ +#include +#include +#include +#include "fiber/libfiber.h" +#include "fiber/libfiber.hpp" + +class myfiber : public acl::fiber { +public: + myfiber(std::vector& locks) : locks_(locks) {} + ~myfiber(void) {} + +private: + std::vector& locks_; + + // @override + void run(void) { + size_t i = acl::fiber::self() % locks_.size(); + acl::fiber_mutex* lock = locks_[i]; + + printf("fiber-%d wait, locks[%zd]=%p\r\n", + acl::fiber::self(), i, lock); + lock->lock(); + printf("fiber-%d locked, locks[%ld]=%p\r\n", + acl::fiber::self(), i, lock); + + sleep(1); + + i = (acl::fiber::self() + 1) % locks_.size(); + lock = locks_[i]; + + printf("fiber-%d wait,locks[%zd]=%p\r\n", + acl::fiber::self(), i, lock); + lock->lock(); + printf("fiber-%d locked, locks[%zd]=%p\r\n", + acl::fiber::self(), i, lock); + } +}; + +class fiber_check : public acl::fiber { +public: + fiber_check(void) {} + ~fiber_check(void) {} + +private: + // @override + void run(void) { + while (true) { + sleep(2); + printf("\r\n"); + acl::fiber_mutex_stats stats; + if (acl::fiber_mutex::deadlock(stats)) { + printf("Deadlock happened!\r\n\r\n"); + show(stats); + } else { + printf("No deadlock happened!\r\n"); + } + printf("=======================================\r\n"); + } + } + + void show(const acl::fiber_mutex_stats& stats) { + for (std::vector::const_iterator + cit = stats.stats.begin(); cit != stats.stats.end(); + ++cit) { + show(*cit); + printf("\r\n"); + } + } + + void show(const acl::fiber_mutex_stat& stat) { + printf("fiber-%d:\r\n", acl::fiber::id(*stat.fb)); + + std::vector stack; + acl::fiber::stacktrace(*stat.fb, stack, 50); + show_stack(stack); + + for (std::vector::const_iterator + cit = stat.holding.begin(); + cit != stat.holding.end(); ++cit) { + printf("Holding mutex=%p\r\n", *cit); + } + printf("Waiting for mutex=%p\r\n", stat.waiting); + } + + void show_stack(const std::vector& stack) + { + for (std::vector::const_iterator + cit = stack.begin(); cit != stack.end(); ++cit) { + printf("0x%lx(%s)+0x%lx\r\n", + (*cit).pc, (*cit).func.c_str(), (*cit).off); + } + } +}; + +static void usage(const char *procname) +{ + printf("usage: %s -h [help] -c fibers_count -n locks_count\r\n", procname); +} + +int main(int argc, char *argv[]) +{ + int i, ch, nlocks = 2, nfibers = 2; + std::vector locks; + + while ((ch = getopt(argc, argv, "hc:n:")) > 0) { + switch (ch) { + case 'h': + usage(argv[0]); + return 0; + case 'c': + nfibers = atoi(optarg); + break; + case 'n': + nlocks = atoi(optarg); + if (nlocks <= 0) { + nlocks = 1; + } + break; + default: + break; + } + } + + for (i = 0; i < nlocks; i++) { + acl::fiber_mutex* lock = new acl::fiber_mutex; + locks.push_back(lock); + } + + std::vector fibers; + + for (i = 0; i < nfibers; i++) { + acl::fiber* fb = new myfiber(locks); + fibers.push_back(fb); + fb->start(); + } + + fiber_check check; + check.start(); + + acl::fiber::schedule(); + + for (std::vector::iterator it = locks.begin(); + it != locks.end(); ++it) { + delete *it; + } + + for (std::vector::iterator it = fibers.begin(); + it != fibers.end(); ++it) { + delete *it; + } + return 0; +} diff --git a/lib_fiber/samples/fiber_stack2/main.cpp b/lib_fiber/samples/fiber_stack2/main.cpp index 0f75957f7..c39549877 100644 --- a/lib_fiber/samples/fiber_stack2/main.cpp +++ b/lib_fiber/samples/fiber_stack2/main.cpp @@ -50,14 +50,12 @@ private: void run(void) { - std::vector stack; - for (int i = 0; i < count_; i++) { + std::vector stack; acl::fiber::stacktrace(*fb_, stack, 50); show_stack(stack); printf("\r\n"); - stack.clear(); sleep(2); }