├── .clang-format ├── .gitignore ├── README.md ├── TinyWeb_logo.png ├── docker.md ├── docs ├── 0.md ├── 1-0.md ├── 1-1.md ├── 1-2.md ├── 1-3.md ├── 1-4.md ├── 1-5.md ├── 1-6.md ├── 1-7.md ├── 1-8.md ├── 2-0.md ├── 2-1.md ├── 2-2.md ├── 2-3.md ├── 2-4.md ├── 2-5.md ├── 3-0.md ├── 3-1.md ├── 3-2.md ├── 3-3.md ├── 3-4.md ├── 3-5.md ├── 4-0.md ├── 4-1.md ├── 4-2.md ├── 4-3.md ├── 4-4.md ├── 4-5.md ├── 4-7.md ├── 5-0.md ├── Idea.md ├── end.md └── install_jekyll.md ├── log ├── TinyWeb.log ├── clear_log.sh ├── debug.log ├── error.log ├── fatal.log ├── info.log └── warn.log ├── src ├── CMakeLists.txt ├── TinyWeb.conf ├── TinyWebConfig.h ├── TinyWebConfig.h.in ├── comment_template.cc ├── debug_TinyWeb.conf ├── http_parser │ ├── README.md │ └── test │ │ ├── bench.c │ │ ├── http_parser.c │ │ ├── http_parser.h │ │ ├── mytest.c │ │ ├── mytest2.c │ │ ├── mytest3.cc │ │ └── test.c ├── mime.types ├── mytest │ ├── CMakeLists.txt │ ├── TinyWebConfig.h │ ├── TinyWebConfig.h.in │ ├── all_test.cc │ ├── builder_test.cc │ ├── chain_test.cc │ ├── dynamicWeb_test.cc │ ├── gzip_files │ │ ├── createTestFiles.sh │ │ ├── source.txt │ │ └── tmp │ │ │ └── createTestFiles.sh │ ├── httpParser_testTmp.cc │ ├── idea2_test.cc │ ├── idea3_test.cc │ ├── idea4_test.cc │ ├── idea_test.cc │ ├── modelCache_test.cc │ ├── modelChunked_test.cc │ ├── modelFcgi_test.cc │ ├── modelFile_test.cc │ ├── modelGzip_test.cc │ ├── parseBody_test.cc │ ├── parseHeaderMeaning_test.cc │ ├── parseHeader_test.cc │ ├── parseHost_test.cc │ ├── parseHttpTime_test.cc │ ├── parseRequestLine_test.cc │ ├── parseResponseLine_test.cc │ ├── parseUrl_test.cc │ └── responser_test.cc ├── prod_TinyWeb.conf ├── test │ ├── CMakeLists.txt │ ├── __master.cc │ ├── __master.h │ ├── accepter_test.cc │ ├── api_test.cc │ ├── base_test.cc │ ├── buffer_test.cc │ ├── cache_test.cc │ ├── client.py │ ├── client_test.cc │ ├── clientpool_test.cc │ ├── configer_test.cc │ ├── connector_test.cc │ ├── currentthread_test.cc │ ├── daemon_test.cc │ ├── defer_test.cc │ ├── dict_test.cc │ ├── fcgi_client_test.cc │ ├── file_test.cc │ ├── gzip_test.cc │ ├── json_test.cc │ ├── list_test.cc │ ├── log_test.cc │ ├── main_test.cc │ ├── master_test.cc │ ├── md5_test.cc │ ├── memorypool_test.cc │ ├── messagequeue_test.cc │ ├── mutex_test.cc │ ├── parser_test.cc │ ├── process_test.cc │ ├── processpool_test.cc │ ├── protocol_test.cc │ ├── proxyer_test.cc │ ├── rbtree_test.cc │ ├── reader_test.cc │ ├── regex.py │ ├── sdstr_test.cc │ ├── semaphore_test.cc │ ├── server.cc │ ├── server.py │ ├── server_test.cc │ ├── sharedmemory_test.cc │ ├── signalmanager_test.cc │ ├── slave_test.cc │ ├── socket_test.cc │ ├── socketpair_test.cc │ ├── sync_test.cc │ ├── test.cc │ ├── test_server.cc │ ├── thread_test.cc │ ├── threadpool_test.cc │ ├── time_test.cc │ └── timerqueue_test.cc ├── tiny_base │ ├── CMakeLists.txt │ ├── api.cc │ ├── api.h │ ├── atomic.h │ ├── buffer.cc │ ├── buffer.h │ ├── condition.cc │ ├── condition.h │ ├── configer.cc │ ├── configer.h │ ├── exception.cc │ ├── exception.h │ ├── file.cc │ ├── file.h │ ├── list_timer.cc │ ├── list_timer.h │ ├── log.cc │ ├── log.h │ ├── md5.cc │ ├── md5.h │ ├── memorypool.cc │ ├── memorypool.h │ ├── messagequeue.cc │ ├── messagequeue.h │ ├── mutex.h │ ├── new_buffer.cc │ ├── new_buffer.h │ ├── reader.cc │ ├── reader.h │ ├── semaphore.cc │ ├── semaphore.h │ ├── sharedmemory.cc │ ├── sharedmemory.h │ ├── signalmanager.cc │ ├── signalmanager.h │ └── sync.h ├── tiny_core │ ├── CMakeLists.txt │ ├── accepter.cc │ ├── accepter.h │ ├── callback.h │ ├── channel.cc │ ├── channel.h │ ├── client.cc │ ├── client.h │ ├── clientpool.cc │ ├── clientpool.h │ ├── connection.cc │ ├── connection.h │ ├── connector.cc │ ├── connector.h │ ├── currentthread.cc │ ├── currentthread.h │ ├── defer.cc │ ├── defer.h │ ├── epoller.cc │ ├── epoller.h │ ├── eventloop.cc │ ├── eventloop.h │ ├── factory.cc │ ├── factory.h │ ├── master.cc │ ├── master.h │ ├── netaddress.cc │ ├── netaddress.h │ ├── process.cc │ ├── process.h │ ├── processpool.cc │ ├── processpool.h │ ├── protocol.cc │ ├── protocol.h │ ├── server.cc │ ├── server.h │ ├── slave.cc │ ├── slave.h │ ├── socket.cc │ ├── socket.h │ ├── socketpair.cc │ ├── socketpair.h │ ├── status.cc │ ├── status.h │ ├── thread.cc │ ├── thread.h │ ├── threadpool.cc │ ├── threadpool.h │ ├── time.cc │ ├── time.h │ ├── timer.cc │ ├── timer.h │ ├── timerid.h │ ├── timerqueue.cc │ └── timerqueue.h ├── tiny_http │ ├── CMakeLists.txt │ ├── http.cc │ ├── http.h │ ├── http_factory.cc │ ├── http_factory.h │ ├── http_model_cache.cc │ ├── http_model_cache.h │ ├── http_model_chunked.cc │ ├── http_model_chunked.h │ ├── http_model_fcgi.cc │ ├── http_model_fcgi.h │ ├── http_model_file.cc │ ├── http_model_file.h │ ├── http_model_gzip.cc │ ├── http_model_gzip.h │ ├── http_parser.cc │ ├── http_parser.h │ ├── http_protocol.cc │ ├── http_protocol.h │ ├── http_proxyer.cc │ ├── http_proxyer.h │ ├── http_responser.cc │ ├── http_responser.h │ ├── http_time.cc │ ├── http_time.h │ ├── str_t.cc │ └── str_t.h ├── tiny_struct │ ├── CMakeLists.txt │ ├── dict_t.cc │ ├── dict_t.h │ ├── list_t.cc │ ├── list_t.h │ ├── rbtree_t.cc │ ├── rbtree_t.h │ ├── sdstr_t.cc │ └── sdstr_t.h └── tmp_TinyWeb.conf └── www ├── 404 ├── 404.html ├── css │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── font-awesome.min.css │ └── style.css ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff └── js │ ├── bootstrap.js │ ├── countUp.js │ ├── custom.js │ └── jquery-1.10.2.js ├── 1-63k_files ├── createTestFiles.sh └── source.txt ├── 404.html ├── 50x.html ├── blog └── blog_home.html ├── favicon.ico ├── filetypes ├── test.css ├── test.gif ├── test.htm ├── test.html ├── test.ico ├── test.jpeg ├── test.jpg ├── test.js ├── test.php └── test.shtml ├── home.html ├── home111.html ├── home_files ├── bootstrap.min.css ├── bootstrap.min.js ├── clike.js ├── codemirror.min.css ├── codemirror.min.js ├── font-awesome.min.css ├── hm.js ├── jquery.min.js ├── modern-business.css └── style.css ├── host_dissigil └── index.html ├── host_general └── index.html ├── image.jpg ├── index.htm ├── index.html ├── index.php ├── sigil └── sigil_home.html ├── test.html ├── test ├── .DS_Store ├── dynamic_download.php ├── dynamic_get.php ├── dynamic_post1.php ├── dynamic_post2.php ├── dynamic_post3.php ├── dynamic_post4.php ├── dynamic_upload.php ├── index.html ├── test.php ├── tinyweb.html └── uploads │ └── TinyWeb_logo.png ├── tinyweb └── tinyweb_home.html └── welcome.html /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | 35 | .vscode 36 | .idea 37 | *.log 38 | *_test 39 | ./log/* 40 | 41 | src/cmake_install.cmake 42 | src/CMakeCache.txt 43 | 44 | src/tiny_base/api\.cc 45 | 46 | src/tiny_core/processpool\.cc 47 | 48 | src/test/build/* 49 | src/mytest/build/* 50 | src/build/* 51 | 52 | www/1-63k_files/*k.txt 53 | -------------------------------------------------------------------------------- /TinyWeb_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/TinyWeb_logo.png -------------------------------------------------------------------------------- /docker.md: -------------------------------------------------------------------------------- 1 | install docker 2 | 3 | apt-get install zlib1g-dev 4 | apt-get install cmake 5 | apt-get install gcc 6 | apt-get install libboost-dev 7 | -------------------------------------------------------------------------------- /docs/0.md: -------------------------------------------------------------------------------- 1 | # **C++构建高性能Web服务器——Step 0:前言** 2 | 3 | 4 | ## **一、想法:** 5 | 6 | - 一直想用C++做个项目,因为比较喜欢网络通信这部分,又让事情变得更有些挑战性,我最终选择实现一个高性能的Web服务器。 7 | 8 | - 在宏观上我希望TinyWeb能够这样: 9 | - 配置简单 10 | - 扩展容易 11 | - 性能高效 12 | - 功能强大 13 | 14 | 15 | - 并希望在开发的过程中能够掌握以下知识: 16 | - Unix环境编程的技能 17 | - Unix网络编程的技能 18 | - 巩固C++11知识 19 | - 掌握构建大型C++项目的技能 20 | - 掌握多进程、多线程同步、通信机制 21 | - 实现高性能可复用Memory-pool 22 | - 掌握基本的数据结构(红黑树、链表、Hash) 23 | - 能够把通用的网络部分作为单独的网络库、为以后网络开发提升效率 24 | 25 | - TinyWeb 目前的功能是: 26 | - 基本的Web服务,只能提供静态网页服务。 27 | - 单进程+Reactor+非阻塞方式运行 28 | - 只能用于Linux系统,不专注跨平台 29 | - 基本的Web服务配置 30 | 31 | - TinyWeb 目前的发展计划: 32 | - 使用进程池的方式提高并发性 33 | - 强有力的支持多种版本Http协议 34 | - 负载均衡功能 35 | - 代理功能 36 | 37 | -------------------------- 38 | 39 | ## **二、系列博客分类** 40 | 41 | 0.[前言]() 42 | 43 | 1.[基础类的介绍&实现]() 44 | 45 | 2.[基本数据结构的实现]() 46 | 47 | 3.[核心类的介绍&实现]() 48 | 49 | 4.[Http逻辑实现]() 50 | 51 | 5.[Http逻辑实现(dynamic response)](s) 52 | 53 | 5.[番外篇--各种难点&实现想法]() 54 | 55 | -------------------------- 56 | 57 | ## **三、设计思想** 58 | 59 | 60 | 61 | ### 1. 网络中最麻烦的是如何处理阻塞的事件: 62 | 63 | > 如果IO事件没有发生,系统阻塞的等待IO事件发生,那么CPU就被 64 | 浪费了,为实现高并发,不能让进程阻塞,CPU等待IO事件. 65 | 借助Linux高效的Epoll机制, 66 | 67 | 至于为何使用Epoll,而不使用Select或Poll,[点这里看看吧](http://blog.csdn.net/russell_tao/article/details/17119729). 68 | 69 | 70 | 71 | ### 2.为了提高并发性:到底是选择多进程还是多线程模式 72 | 73 | > 多进程与多线程各有优缺点,并且大部分是互补的,具体就不再赘述了, 74 | > 详情请[戳这里](https://www.cnblogs.com/zhanht/p/5401685.html) 75 | > 我选择多进程的原因是: 76 | > 1. 安全性高,一个进程崩溃不会影响别的进程 77 | > 2. 容易调试,不易造成死锁 78 | > 3. 有较为成熟的进程间通信\同步机制(共享内存,信号,文件锁,socketpair....) 79 | 80 | > 在接受客户端连接的时候,如何再去创建一个进程,效率低下.故因此采用进程池的方式: 81 | Master进程为父进程,主要控制子进程的状态;可动态配置数量的Slave子进程,用于接受连接, 82 | 处理Http逻辑. 83 | 84 | ### 3.C++最难管理的还是内存 85 | 86 | 87 | > 为了方便的进行内存管理,我设计了一个内存池,不会产生大量的内存碎片,性能待测试.以后还会 88 | 介绍如何实现的,尽请期待. 89 | 90 | 91 | ### 4.进程间通信的方式很多,到底选择哪几个 92 | 93 | > 了解了下Nginx,有考虑了使用的复杂度,我决定使用这几个通信.同步机制 94 | > - 原子操作 95 | > - 信号量 96 | > - 消息队列 97 | > - 共享内存 98 | > - 信号 99 | 100 | 101 | -------------------------- 102 | 103 | ## **四、源码** 104 | 105 | 想要源代码的请[戳这里](https://github.com/GeneralSandman/TinyWeb),希望大家多多对代码风格做出评判,毕竟自己只是个大三的学生. 106 | 107 | -------------------------- 108 | 109 | ## **五、参考文献** 110 | 111 | 小伙伴想要了解更多的高性能的网络编程,推荐一个[大神的专栏](http://blog.csdn.net/column/details/high-perf-network.html) -------------------------------------------------------------------------------- /docs/1-0.md: -------------------------------------------------------------------------------- 1 | # **C++构建高性能Web服务器——Step 1:基础类的介绍&实现** 2 | 3 | 4 | ## **一、基础类全篇** 5 | 6 | 0.[序]() 7 | 8 | 1.[Logger类实现日志功能]() 9 | 10 | 2.[Configer类实现配置日志功能]() 11 | 12 | 3.[MemoryPool实现]() 13 | 14 | 4.[SignalManager实现]() 15 | 16 | 5.[网络缓冲区Buffer实现]() 17 | 18 | 6.[Time实现]() 19 | 20 | 7.[api.h/api.cc介绍]() 21 | 22 | 8.[异常Exception类]() 23 | 24 | ## **二、想法** 25 | 26 | 这一系列文章主要介绍TinyWeb基础类的实现,如何对操作系统调用进行封装,为后续开发提供更人性化的API,把系统调用中很少用到的参数,不方便赋值的参数给屏蔽掉。方便使用,方便调试,及时输出错误信息。 27 | 28 | 29 | ## **End、系列博客分类** -------------------------------------------------------------------------------- /docs/1-2.md: -------------------------------------------------------------------------------- 1 | # **C++构建高性能Web服务器——Step 1-2:Configer类实现配置日志功能** 2 | 3 | ## **一、基础类全篇** 4 | 5 | ## **** 6 | 7 | ## **** 8 | 9 | 10 | > ## 1.Configer的使用方法 11 | 12 | - 获得Configer实例(配置项还未加载,需调用loadConfig()) 13 | ``` 14 | Configer &getConfigerInstance(const std::string file = "") 15 | ``` 16 | 17 | - 调整confige文件 18 | ``` 19 | setConfigerFile(const std::string &file) 20 | ``` 21 | 22 | - 装载配置文件(不需调用,setConfigerFile会装载配置文件) 23 | ``` 24 | loadConfig() 25 | ``` 26 | 27 | - 获取配置项数值 28 | ``` 29 | std::string getConfigValue(const std::string &); 30 | ``` 31 | 32 | - 注意 33 | 34 | 这样会出错: 35 | ``` 36 | Configer configer = Configer::getConfigerInstance(); 37 | ``` 38 | 39 | 必须用引用接受: 40 | ``` 41 | Configer &configer = Configer::getConfigerInstance(); 42 | ``` 43 | 44 | 推荐用法 1: 45 | ``` 46 | std::string a = "../TinyWeb.conf"; 47 | setConfigerFile(a); 48 | if (loadConfig()) 49 | std::cout << "load config successfull\n"; 50 | else 51 | std::cout << "load config failed\n"; 52 | Configer::getConfigerInstance().test(); 53 | cout << getConfigValue("loglevel"); 54 | ``` 55 | 56 | 使用方法 2: 57 | ``` 58 | Configer &configer = Configer::getConfigerInstance(); 59 | configer.setConfigerFile("../TinyWeb.conf"); 60 | if (configer.loadConfig()) 61 | std::cout << "load config successfull\n"; 62 | else 63 | std::cout << "load config failed\n"; 64 | configer.test(); 65 | cout << configer.getConfigValue("loglevel"); 66 | ``` 67 | 68 | ``` 69 | 70 | ``` 71 | 72 | 73 | ## 想法: 74 | 75 | ## **** 76 | 77 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/1-3.md: -------------------------------------------------------------------------------- 1 | 2 | # **C++构建高性能Web服务器——Step 1-3:MemoryPool实现** 3 | 4 | ## **一、基础类全篇** 5 | 6 | ## **二、想法** 7 | 内存池的作用在于消除频繁调用系统默认的内存分配和释放函数所带来的开销问题。 8 | 由于每次要求分配的内存大小不等,使用默认的内存分配函数的话,可能给系统带来大量的碎片问题,所以,将内存配置问题交给底层的内存池去处理,是一个不错的选择。 9 | 10 | ## **** 11 | 12 | ## **** 13 | 14 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/1-4.md: -------------------------------------------------------------------------------- 1 | 2 | # **C++构建高性能Web服务器——Step 1-4:SignalManager实现** 3 | 4 | ## **一、基础类全篇** 5 | ## **** 6 | 7 | ## **** 8 | 9 | ## **** 10 | 11 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/1-5.md: -------------------------------------------------------------------------------- 1 | 2 | # **C++构建高性能Web服务器——Step 1-5:网络缓冲区Buffer实现* 3 | 4 | ## **一、基础类全篇** 5 | ## **** 6 | 7 | ## **** 8 | 9 | ## **** 10 | 11 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/1-6.md: -------------------------------------------------------------------------------- 1 | 2 | # **C++构建高性能Web服务器——Step 1-7:Time实现* 3 | 4 | ## **一、基础类全篇** 5 | ## **** 6 | 7 | ## **** 8 | 9 | ## **** 10 | 11 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/1-7.md: -------------------------------------------------------------------------------- 1 | 2 | # **C++构建高性能Web服务器——Step 1-7:api.h/api.cc介绍** 3 | 4 | ## **一、基础类全篇** 5 | ## **** 6 | 7 | ## **** 8 | 9 | ## **** 10 | 11 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/1-8.md: -------------------------------------------------------------------------------- 1 | 2 | # **C++构建高性能Web服务器——Step 1-8:异常Exception类实现* 3 | 4 | ## **一、基础类全篇** 5 | ## **** 6 | 7 | ## **** 8 | 9 | ## **** 10 | 11 | ## **End、参考资料** -------------------------------------------------------------------------------- /docs/2-0.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/2-0.md -------------------------------------------------------------------------------- /docs/2-1.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/2-1.md -------------------------------------------------------------------------------- /docs/2-2.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/2-2.md -------------------------------------------------------------------------------- /docs/2-3.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/2-3.md -------------------------------------------------------------------------------- /docs/2-4.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/2-4.md -------------------------------------------------------------------------------- /docs/2-5.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/2-5.md -------------------------------------------------------------------------------- /docs/3-0.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/3-0.md -------------------------------------------------------------------------------- /docs/3-1.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/3-1.md -------------------------------------------------------------------------------- /docs/3-2.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/3-2.md -------------------------------------------------------------------------------- /docs/3-3.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/3-3.md -------------------------------------------------------------------------------- /docs/3-4.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/3-4.md -------------------------------------------------------------------------------- /docs/3-5.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/3-5.md -------------------------------------------------------------------------------- /docs/4-2.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/4-2.md -------------------------------------------------------------------------------- /docs/4-3.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/4-3.md -------------------------------------------------------------------------------- /docs/4-4.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/4-4.md -------------------------------------------------------------------------------- /docs/5-0.md: -------------------------------------------------------------------------------- 1 | # **C++构建高性能Web服务器——Step 4-0:Http协议的实现** 2 | 3 | 4 | ## **一、想法:** 5 | 6 | - 通过[第四章](),我们大概了解了TinyWeb在处理静态资源时的逻辑,本章主要介绍TinyWeb是如何处理动态请求的. 7 | 8 | ## **二、什么是动态请求:** 9 | 10 | 动态页面就是我们看见的有特效的、会动的Web页面么,答案时否定的. 11 | 12 | 我们可以这样理解: 静态页面就是程序员已经写好的Html+js+css页面,放在服务器上,是不会改变的,除非程序员再去编辑页面. 加入设计一个qq空间的页面, 其实每个人的qq空间的布局是相同的.(截图),比如:头部是导航栏,右边是最近访客, 那如果每个人qq空间都采用静态页面来设计的时候, 每个qq空间都必须有一套自己的html+js+css,这样对于系统资源消耗,用户能不能快速的添加内容,这就是个灾难...所以程序员 13 | 14 | 15 | ## **三、TinyWeb和Fcgi服务器的关系是什么** 16 | 17 | 在处理动态页面的时候, -------------------------------------------------------------------------------- /docs/end.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/docs/end.md -------------------------------------------------------------------------------- /docs/install_jekyll.md: -------------------------------------------------------------------------------- 1 | http://blog.csdn.net/qq_30490125/article/details/51338101 2 | http://blog.csdn.net/chszs/article/details/42462517 3 | baixin.io/2016/10/jekyll_tutorials1 -------------------------------------------------------------------------------- /log/TinyWeb.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/log/TinyWeb.log -------------------------------------------------------------------------------- /log/clear_log.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd `dirname $0` 4 | echo "clear log file:"$(pwd)"/*" 5 | 6 | rm *.log 7 | 8 | touch debug.log 9 | touch error.log 10 | touch info.log 11 | touch warn.log 12 | touch fatal.log 13 | touch TinyWeb.log -------------------------------------------------------------------------------- /log/debug.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/log/debug.log -------------------------------------------------------------------------------- /log/error.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/log/error.log -------------------------------------------------------------------------------- /log/fatal.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/log/fatal.log -------------------------------------------------------------------------------- /log/info.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/log/info.log -------------------------------------------------------------------------------- /log/warn.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/log/warn.log -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # main CMakeLists.txt 2 | 3 | cmake_minimum_required(VERSION 2.8) 4 | project (TinyWeb) 5 | 6 | set (TINYWEB_VERSION "\"TnyWeb/0.0.8\"") 7 | set (SHARED_MEMORY_ANON 1) 8 | set (SHARED_MEMORY_DEVZERO 0) 9 | set (SHARED_MEMORY_SYSVSHM 0) 10 | 11 | # configure a header file to pass some of the CMake settings 12 | # to the source code 13 | configure_file ( 14 | "${PROJECT_SOURCE_DIR}/TinyWebConfig.h.in" 15 | "${PROJECT_SOURCE_DIR}/TinyWebConfig.h" 16 | ) 17 | 18 | add_definitions("-Wall -std=c++11") 19 | 20 | SET (SOURCE_DIR ./) 21 | 22 | include_directories(${SOURCE_DIR}) 23 | 24 | add_subdirectory("${SOURCE_DIR}/tiny_base" tiny_base.out) 25 | add_subdirectory("${SOURCE_DIR}/tiny_core" tiny_core.out) 26 | add_subdirectory("${SOURCE_DIR}/tiny_http" tiny_http.out) 27 | add_subdirectory("${SOURCE_DIR}/tiny_struct" tiny_struct.out) 28 | 29 | 30 | add_executable(TinyWeb 31 | main.cc) 32 | 33 | target_link_libraries(TinyWeb 34 | tiny_http_model 35 | tiny_core_model 36 | tiny_struct_model 37 | tiny_base_model 38 | ) 39 | -------------------------------------------------------------------------------- /src/TinyWebConfig.h: -------------------------------------------------------------------------------- 1 | #define TINYWEB_VERSION "TinyWeb/0.0.8" 2 | #define SHARED_MEMORY_ANON 1 3 | #define SHARED_MEMORY_DEVZERO 0 4 | #define SHARED_MEMORY_SYSVSHM 0 5 | -------------------------------------------------------------------------------- /src/TinyWebConfig.h.in: -------------------------------------------------------------------------------- 1 | #define TINYWEB_VERSION @TINYWEB_VERSION@ 2 | #define SHARED_MEMORY_ANON 1 3 | #define SHARED_MEMORY_DEVZERO 0 4 | #define SHARED_MEMORY_SYSVSHM 0 5 | -------------------------------------------------------------------------------- /src/comment_template.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/http_parser/test/mytest3.cc: -------------------------------------------------------------------------------- 1 | #include "my_http_parser.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | #define offsetof__(s, m) (size_t) & (((s *)0)->m) 10 | 11 | int main() 12 | { 13 | HttpHeaders *headers = new HttpHeaders; 14 | std::cout << sizeof(*headers) << std::endl; 15 | std::cout << sizeof(headers->host) << std::endl; 16 | std::cout << offsetof__(HttpHeaders, host) << std::endl; 17 | std::cout << offsetof__(HttpHeaders, connection) << std::endl; 18 | 19 | delete headers; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /src/mytest/TinyWebConfig.h: -------------------------------------------------------------------------------- 1 | #define TINYWEB_VERSION "TinyWeb/0.0.10" 2 | -------------------------------------------------------------------------------- /src/mytest/TinyWebConfig.h.in: -------------------------------------------------------------------------------- 1 | #define TINYWEB_VERSION @TINYWEB_VERSION@ 2 | -------------------------------------------------------------------------------- /src/mytest/all_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/mytest/chain_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main() 22 | { 23 | std::string str = "helloworld+"; 24 | std::vector strs; 25 | for (auto i=0; i<10 ;i++) 26 | strs.push_back(str); 27 | 28 | http_chain_t * chain_head = nullptr; 29 | 30 | http_chain_t *curr = chain_head; 31 | http_chain_t *pre = nullptr; 32 | 33 | for (auto i=0; i<10; i++) 34 | { 35 | if (nullptr == curr) 36 | { 37 | curr = new http_chain_t; 38 | if(nullptr == chain_head) 39 | chain_head = curr; 40 | curr->buffer.begin = strs[i].c_str(); 41 | curr->buffer.end = strs[i].c_str() + strs[i].size(); 42 | curr->next = nullptr; 43 | } 44 | 45 | if (nullptr != pre) 46 | { 47 | pre->next = curr; 48 | } 49 | 50 | pre = curr; 51 | curr = curr->next; 52 | } 53 | 54 | curr = chain_head; 55 | 56 | while(nullptr != curr) 57 | { 58 | printf("%.*s", curr->buffer.end - curr->buffer.begin, curr->buffer.begin); 59 | curr = curr->next; 60 | } 61 | 62 | curr = chain_head; 63 | while(nullptr != curr) 64 | { 65 | pre = curr->next; 66 | delete curr; 67 | curr = pre; 68 | } 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /src/mytest/dynamicWeb_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | using namespace std; 17 | 18 | typedef struct 19 | { 20 | const char* str; 21 | 22 | bool valid; 23 | const char* response_str; 24 | 25 | 26 | } ; 27 | 28 | int main() { 29 | 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/mytest/gzip_files/createTestFiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | fillFile(){ 4 | file=$1"k" 5 | echo "create file:"$file 6 | touch $file 7 | 8 | i=1 9 | while(($i<=$1)) 10 | do 11 | cat source.txt >> $file 12 | let "i++" 13 | done 14 | 15 | } 16 | 17 | echo "create gzip test files\n" 18 | n=1 19 | while(($n<=63)) 20 | do 21 | fillFile $n 22 | let "n++" 23 | done 24 | -------------------------------------------------------------------------------- /src/mytest/gzip_files/source.txt: -------------------------------------------------------------------------------- 1 | 123456789 2 | 123456789 3 | 123456789 4 | 123456789 5 | 123456789 6 | 123456789 7 | 123456789 8 | 123456789 9 | 123456789 10 | 123456789 11 | 123456789 12 | 123456789 13 | 123456789 14 | 123456789 15 | 123456789 16 | 123456789 17 | 123456789 18 | 123456789 19 | 123456789 20 | 123456789 21 | 123456789 22 | 123456789 23 | 123456789 24 | 123456789 25 | 123456789 26 | 123456789 27 | 123456789 28 | 123456789 29 | 123456789 30 | 123456789 31 | 123456789 32 | 123456789 33 | 123456789 34 | 123456789 35 | 123456789 36 | 123456789 37 | 123456789 38 | 123456789 39 | 123456789 40 | 123456789 41 | 123456789 42 | 123456789 43 | 123456789 44 | 123456789 45 | 123456789 46 | 123456789 47 | 123456789 48 | 123456789 49 | 123456789 50 | 123456789 51 | 123456789 52 | 123456789 53 | 123456789 54 | 123456789 55 | 123456789 56 | 123456789 57 | 123456789 58 | 123456789 59 | 123456789 60 | 123456789 61 | 123456789 62 | 123456789 63 | 123456789 64 | 123456789 65 | 123456789 66 | 123456789 67 | 123456789 68 | 123456789 69 | 123456789 70 | 123456789 71 | 123456789 72 | 123456789 73 | 123456789 74 | 123456789 75 | 123456789 76 | 123456789 77 | 123456789 78 | 123456789 79 | 123456789 80 | 123456789 81 | 123456789 82 | 123456789 83 | 123456789 84 | 123456789 85 | 123456789 86 | 123456789 87 | 123456789 88 | 123456789 89 | 123456789 90 | 123456789 91 | 123456789 92 | 123456789 93 | 123456789 94 | 123456789 95 | 123456789 96 | 123456789 97 | 123456789 98 | 123456789 99 | 123456789 100 | 123456789 101 | 123456789 102 | 123456789 103 | 123 104 | -------------------------------------------------------------------------------- /src/mytest/gzip_files/tmp/createTestFiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | fillFile(){ 4 | file=$1"k" 5 | echo "create file:"$file 6 | touch $file 7 | 8 | i=1 9 | while(($i<=$1)) 10 | do 11 | cat source.txt >> $file 12 | let "i++" 13 | done 14 | 15 | } 16 | 17 | echo "create gzip test files\n" 18 | n=1 19 | while(($n<=63)) 20 | do 21 | fillFile $n 22 | let "n++" 23 | done 24 | -------------------------------------------------------------------------------- /src/mytest/idea4_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | struct cmp_str 22 | { 23 | bool operator()(char const *a, char const *b) 24 | { 25 | return std::strcmp(a, b) < 0; 26 | } 27 | }; 28 | 29 | 30 | int main() 31 | { 32 | std::string filename = "/home/tinyweb/src/mytest/build/6/33/0d70dd3c42e1e544abe8f7c77a9ea0"; 33 | std::vector filenames = { 34 | "" 35 | } 36 | 37 | std::string tmp; 38 | std::vector dirs; 39 | 40 | for (int i=0;i 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | using namespace std; 21 | 22 | void initConfige() 23 | { 24 | 25 | } 26 | 27 | void testFile() 28 | { 29 | std::string file = "../../TinyWeb.conf"; 30 | Configer& configer = Configer::getConfigerInstance(); 31 | configer.setConfigerFile(file); 32 | 33 | bool debug = true; 34 | if (0 == configer.loadConfig(debug)) 35 | std::cout << "++load config successfull\n"; 36 | else 37 | std::cout << "--load config failed\n"; 38 | std::cout << std::endl; 39 | 40 | std::string servername = "dissigil.cn"; 41 | std::string wwwpath; 42 | 43 | ServerConfig server = configer.getServerConfig(servername); 44 | wwwpath = server.www; 45 | 46 | std::cout << "indexpage:"; 47 | for (auto t : server.indexpage) { 48 | std::cout << t << " "; 49 | } 50 | std::cout << std::endl; 51 | 52 | vector files; 53 | files.push_back("/"); 54 | files.push_back("/index.html"); 55 | files.push_back("/index.htm"); 56 | files.push_back("/index.php"); 57 | files.push_back("/test/test.php"); 58 | files.push_back("/blog/"); 59 | files.push_back("/tests/"); 60 | files.push_back("/ajsldfaj.html"); 61 | 62 | int file_type; 63 | int return_val; 64 | 65 | for (auto f : files) { 66 | 67 | f = wwwpath + f; 68 | std::cout << f << std::endl; 69 | 70 | HttpFile file; 71 | file_type = isRegularFile(f); 72 | if (0 == file_type) { 73 | std::cout << "file:\n"; 74 | return_val = file.setFile(f); 75 | } else if (1 == file_type) { 76 | std::cout << "path:\n"; 77 | return_val = file.setPathWithDefault(f, server.indexpage); 78 | // TODO:if hasn't default index page in , go to sepical file 79 | } else if (-1 == file_type) { 80 | std::cout << "sepical file:\n"; 81 | } 82 | 83 | if (!return_val) { 84 | std::cout << "++file exit" << std::endl; 85 | } else { 86 | std::cout << "--file not exit" << std::endl; 87 | } 88 | 89 | std::cout << std::endl; 90 | } 91 | } 92 | 93 | void testFile2() 94 | { 95 | } 96 | 97 | int main() 98 | { 99 | testFile(); 100 | testFile2(); 101 | 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /src/test/__master.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---class Master--- 9 | * 10 | * this class will do those things: 11 | * switch to daemon process 12 | * new Protocol,new Server; 13 | * server->start() and eventloop->loop(); 14 | **************************************** 15 | *Server():initalize the Server and Protocol 16 | *start():invoke Server::start(),EventLoop::loop() 17 | *~Server():delete the resource; 18 | */ 19 | 20 | #ifndef MASTER_H 21 | #define MASTER_H 22 | 23 | #include 24 | 25 | #include 26 | 27 | class EventLoop; 28 | class Server; 29 | class Protocol; 30 | class Factory; 31 | 32 | void logSecond(); 33 | 34 | class Master { 35 | private: 36 | static EventLoop* m_pEventLoop; 37 | std::string m_nConfigFile; 38 | NetAddress m_nAddress; 39 | Protocol* m_pProtocol; 40 | Factory* m_pFactory; 41 | Server* m_pServer; 42 | 43 | void m_fSwitchtoDaemon(); 44 | void m_fSetSignalsHandler(); 45 | static void m_fSignalHandler(int); 46 | 47 | public: 48 | Master(const std::string& configfile, bool Debug = false); 49 | void start(); 50 | ~Master(); 51 | }; 52 | 53 | #endif // !MASTER_H 54 | -------------------------------------------------------------------------------- /src/test/accepter_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | int number = 0; 26 | 27 | EventLoop *g_loop = nullptr; 28 | 29 | void ConnectionCallback(int connectfd, const NetAddress &peer) 30 | { 31 | string info = to_string(++number); 32 | cout << "new Connection:" << peer.getIpPort() << endl; 33 | cout << "write to:" << peer.getIpPort() << endl; 34 | writeString(connectfd, info); 35 | close(connectfd); 36 | } 37 | 38 | void fun1() 39 | { 40 | cout << "invoke per second\n"; 41 | } 42 | 43 | void timeout() 44 | { 45 | cout << "Timeout!\n"; 46 | g_loop->quit(); 47 | } 48 | 49 | int main() 50 | { 51 | g_loop = new EventLoop(); 52 | g_loop->runEvery(1, boost::bind(fun1)); 53 | g_loop->runAfter(200, boost::bind(timeout)); 54 | 55 | NetAddress server("127.0.0.1:9898"); 56 | Accepter accept(g_loop, server,createNoBlockSocket()); 57 | accept.setConnectionCallback(ConnectionCallback); 58 | accept.listen(); 59 | 60 | g_loop->loop(); 61 | delete g_loop; 62 | return 0; 63 | } -------------------------------------------------------------------------------- /src/test/api_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | using namespace std; 17 | 18 | int main() 19 | { 20 | int a; 21 | cin >> a; 22 | if (a == 1) 23 | { 24 | char s[] = "error"; 25 | handle_error(s); 26 | } 27 | if (a == 2) 28 | { 29 | string s = "error"; 30 | handle_error_s(s); 31 | } 32 | if (a == 3) 33 | { 34 | handle_error("error"); 35 | } 36 | if (a == 4) 37 | { 38 | handle_error_s("error"); 39 | } 40 | return 0; 41 | } -------------------------------------------------------------------------------- /src/test/base_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | EventLoop *g_loop = nullptr; 24 | 25 | void timeout() 26 | { 27 | cout << "Timeout!\n"; 28 | g_loop->quit(); 29 | } 30 | 31 | void fun1() 32 | { 33 | cout << "invoke per second\n"; 34 | } 35 | 36 | void fun2() 37 | { 38 | cout << "invoke per 2 seconds\n"; 39 | } 40 | 41 | void fun3() 42 | { 43 | cout << "invoke per 3 seconds\n"; 44 | } 45 | 46 | int main() 47 | { 48 | 49 | g_loop = new EventLoop(); 50 | 51 | g_loop->runEvery(1, boost::bind(fun1)); 52 | g_loop->runEvery(2, boost::bind(fun2)); 53 | g_loop->runEvery(3, boost::bind(fun3)); 54 | g_loop->runAfter(10, boost::bind(timeout)); 55 | 56 | g_loop->loop(); 57 | delete g_loop; 58 | return 0; 59 | } -------------------------------------------------------------------------------- /src/test/buffer_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | 18 | using namespace std; 19 | 20 | int main() 21 | { 22 | { 23 | Buffer out; 24 | out.append("abc"); 25 | out.append("abc"); 26 | out.append("abc"); 27 | out.append("abc"); 28 | out.append("abc"); 29 | cout << out.get(3) << endl; 30 | cout << out.getAll() << endl; 31 | } 32 | 33 | { 34 | Buffer out; 35 | vector request; 36 | 37 | std::string httpRequest = "GET / HTTP/1.0\r\n"; 38 | std::string httpRequest2 = "Host: localhost:9595\r\n"; 39 | std::string httpRequest3 = "Accept: text/html\r\n"; 40 | std::string httpRequest4 = "Accept-Encoding: gzip, compress, bzip2\r\n"; 41 | std::string httpRequest5 = "Accept-Language: en\r\n"; 42 | std::string httpRequest6 = "User-Agent: Lynx/2.8.9dev.8 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/3.4.9\r\n"; 43 | std::string end = "\r\n"; 44 | 45 | out.append(httpRequest); 46 | out.append(httpRequest2); 47 | out.append(httpRequest3); 48 | out.append(httpRequest4); 49 | out.append(httpRequest5); 50 | out.append(httpRequest6); 51 | out.append(end); 52 | 53 | string line; 54 | int i = 0; 55 | while (out.getALine(line)) 56 | { 57 | std::cout << i++ << "-" << line << "-\n"; 58 | line = ""; 59 | } 60 | } 61 | 62 | return 0; 63 | } -------------------------------------------------------------------------------- /src/test/cache_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | 18 | 19 | using namespace std; 20 | 21 | int main() 22 | { 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /src/test/client.py: -------------------------------------------------------------------------------- 1 | import socket, sys,time 2 | 3 | 4 | def sleepSecond(s): 5 | print "sleep ",s,"second(s)" 6 | time.sleep(s) 7 | 8 | def client1(localport,ip, port): 9 | lport=int(localport) 10 | while(1): 11 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 12 | s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 13 | s.bind(("127.0.0.1", lport)) 14 | lport+=1 15 | s.connect((ip, int(port))) 16 | sleepSecond(1) 17 | s.close() 18 | 19 | def client(localport,ip, port): 20 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 21 | s.bind(("127.0.0.1", int(localport))) 22 | s.connect((ip, int(port))) 23 | 24 | print 'server address:', s.getpeername() 25 | 26 | sleepSecond(3) 27 | print "send message:I'm client" 28 | s.send("I'm client") 29 | 30 | buf=s.recv(100) 31 | print buf 32 | 33 | sleepSecond(3) 34 | print "close connection" 35 | s.close() 36 | 37 | def webClient(localport,ip,port=9999): 38 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 39 | s.bind(("127.0.0.1", int(localport))) 40 | s.connect((ip, int(port))) 41 | print 'server address:', s.getpeername() 42 | 43 | r1 = "GET /index.html HTTP/1.1\r\n" 44 | r2 = "host: localhost:9999\r\n" 45 | r3="connection: Close\r\n\r\n" 46 | r=r1+r2+r3 47 | 48 | # for num in range(1,1000): 49 | s.send(r) 50 | buf =s.recv(5000) 51 | print len(buf) 52 | 53 | sleepSecond(12) 54 | # print num 55 | s.close() 56 | 57 | 58 | 59 | if __name__ == "__main__": 60 | 61 | webClient(sys.argv[3], sys.argv[1], sys.argv[2]) 62 | -------------------------------------------------------------------------------- /src/test/currentthread_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | void *thr_fun(void *) 23 | { 24 | pid_t main_pid = getpid(); 25 | cout << "thr_fun pid:" << main_pid << endl; 26 | } 27 | int main() 28 | { 29 | pid_t main_pid = getpid(); 30 | cout << "main pid:" << main_pid << endl; 31 | 32 | pthread_t ntid; 33 | int res = pthread_create(&ntid, NULL, thr_fun, NULL); 34 | if (res != 0) 35 | handle_error("pthread_create error"); 36 | 37 | sleep(1); 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /src/test/daemon_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | using namespace std; 38 | 39 | EventLoop *g_loop = nullptr; 40 | 41 | static void m_fSignalHandler(int sig) 42 | { 43 | if (g_loop) 44 | g_loop->quit(); 45 | } 46 | 47 | void m_fInit() 48 | { 49 | //first step: 50 | //add signal handler 51 | add_signal(SIGTERM, m_fSignalHandler); 52 | add_signal(SIGINT, m_fSignalHandler); 53 | } 54 | 55 | void fun1() 56 | { 57 | LOG(Info) << "info-\n"; 58 | } 59 | 60 | int main() 61 | { 62 | //signal 63 | headerMeaningInit(); //TODO:delete 64 | 65 | add_signal(SIGTERM, m_fSignalHandler); 66 | add_signal(SIGINT, m_fSignalHandler); 67 | 68 | g_loop = new EventLoop(); 69 | g_loop->runEvery(1, boost::bind(fun1)); 70 | 71 | int listenFd = createNoBlockSocket(); 72 | NetAddress address("127.0.0.1:9090"); 73 | struct sockaddr_in s = address.getAddr(); 74 | Bind(listenFd, &s); 75 | 76 | WebProtocol prot; 77 | Factory *factory = new Factory(g_loop, &prot); 78 | Server server(g_loop, address, listenFd, factory); 79 | 80 | server.start(); 81 | 82 | g_loop->loop(); 83 | delete g_loop; 84 | delete factory; 85 | return 0; 86 | } -------------------------------------------------------------------------------- /src/test/defer_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | void succ1() 25 | { 26 | std::cout << "succ1():no throwing exception\n"; 27 | } 28 | 29 | void fail1(Exception &exc) 30 | { 31 | std::cout << "fail1():no throwing exception\n"; 32 | } 33 | 34 | void succ2() 35 | { 36 | std::cout << "succ2():throw exception[error3]\n"; 37 | Exception e("error3"); 38 | throw e; 39 | } 40 | 41 | void fail2(Exception &exc) 42 | { 43 | std::cout << "fail2():catch exceptrion and no throwing exception\n"; 44 | std::cout << exc.what() << std::endl; 45 | } 46 | 47 | void succ3() 48 | { 49 | std::cout << "succ3():throw exception\n"; 50 | Exception e("error4"); 51 | throw e; 52 | } 53 | 54 | void fail3(Exception &exc) 55 | { 56 | std::cout << "fail3():catch exceptrion and throw exception\n"; 57 | std::cout << exc.what() << std::endl; 58 | Exception e("error5"); 59 | throw e; 60 | } 61 | 62 | void doneSucc() 63 | { 64 | std::cout << "chains done\n"; 65 | } 66 | 67 | void doneFail(Exception &exc) 68 | { 69 | std::cout << "chains done with error\n"; 70 | } 71 | 72 | int main() 73 | { 74 | Defer defer; 75 | 76 | defer.addCallBack(succ1); 77 | defer.addErrorBack(fail1); 78 | 79 | defer.addCallBack(succ2); 80 | defer.addErrorBack(fail2); 81 | 82 | defer.addCallBack(succ3); 83 | defer.addErrorBack(fail3); 84 | 85 | defer.addErrorBack(doneFail); 86 | 87 | defer.callback(); 88 | return 0; 89 | } -------------------------------------------------------------------------------- /src/test/dict_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | int main() 23 | { 24 | { 25 | string d = "db"; 26 | Dict newdict(d); 27 | 28 | for (int i = 0; i < 10; i++) 29 | { 30 | string key, value; 31 | key += char(98 + i); 32 | value = key; 33 | cout << key << ":" << value << endl; 34 | 35 | newdict.dictSet(key, value); 36 | } 37 | cout << "len:" << newdict.dictLen() << endl; 38 | 39 | DictIter iter(&newdict); 40 | DictEntry *next = nullptr; 41 | while ((next = iter.getDictNext()) != nullptr) 42 | { 43 | cout << next->getKey() << ":" << next->getValue() << endl; 44 | } 45 | cout<<"----\n"; 46 | iter.reset2Begin(); 47 | while ((next = iter.getDictNext()) != nullptr) 48 | { 49 | cout << next->getKey() << ":" << next->getValue() << endl; 50 | } 51 | } 52 | 53 | return 0; 54 | } -------------------------------------------------------------------------------- /src/test/list_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | int main() 23 | { 24 | 25 | { 26 | List l("test"); 27 | for (int i = 0; i < 5; i++) 28 | l.add_head("a"); 29 | 30 | std::cout << "---------\n"; 31 | std::cout << "test getByIndex()\n"; 32 | string value; 33 | for (int i = 0; i < 10; i++) 34 | { 35 | if (l.getByIndex(i, value)) 36 | std::cout << "get index " << i << ":" << value << std::endl; 37 | } 38 | 39 | std::cout << "---------\n"; 40 | std::cout << "test setByIndex()\n"; 41 | for (int i = 0; i < 10; i++) 42 | { 43 | if (l.setByIndex(i, "value")) 44 | std::cout << "set index " << i << ":" 45 | << "value" << std::endl; 46 | } 47 | 48 | std::cout << "---------\n"; 49 | std::cout << "test getByRange()\n"; 50 | vector res; 51 | if (l.getByRange(res, 0, 4)) 52 | { 53 | for (auto t : res) 54 | cout << t << " "; 55 | cout << endl; 56 | } 57 | 58 | std::cout << "---------\n"; 59 | std::cout << "test getAll()\n"; 60 | vector aa; 61 | if (l.getAll(aa)) 62 | { 63 | for (auto t : aa) 64 | cout << t << " "; 65 | cout << endl; 66 | } 67 | } 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /src/test/master_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | int main(int argc, char **argv) 23 | { 24 | { 25 | //default config file 26 | string config_file = "/home/li/TinyWeb/TinyWeb.conf"; 27 | bool debug = false; 28 | 29 | //parse arg line 30 | struct option longopts[] = { 31 | {"configfile", 1, NULL, 'c'}, 32 | {"debug", 0, NULL, 'd'}, 33 | {0, 0, 0, 0}, 34 | }; 35 | const char *short_options = "c:d"; 36 | int c; 37 | while ((c = getopt_long(argc, argv, short_options, longopts, NULL)) != -1) 38 | { 39 | if (c == 'c') 40 | { 41 | config_file = optarg; 42 | } 43 | else if (c == 'd') 44 | { 45 | debug = true; 46 | } 47 | } 48 | // 49 | 50 | //check config file 51 | if (access(config_file.c_str(), 0) == -1) 52 | { 53 | std::cout << "The file(" << config_file << ") doesn't exist" << std::endl; 54 | exit(-1); 55 | } 56 | 57 | Master master(config_file,debug); 58 | master.start(); 59 | } 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /src/test/md5_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | static const char b64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 20 | 21 | /* "/" replaced with "-" */ 22 | static const char b64fss[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; 23 | 24 | int b64cpy(char* dst, const char* src, int n, int fss) 25 | { 26 | const char* b = fss ? b64fss : b64; 27 | int i, j; 28 | 29 | j = 0; 30 | for (i = 0; i < n; i += 3) { 31 | unsigned char a0, a1, a2; 32 | a0 = src[i]; 33 | a1 = i < n - 1 ? src[i + 1] : 0; 34 | a2 = i < n - 2 ? src[i + 2] : 0; 35 | dst[j++] = b[(a0 >> 2) & 0x3F]; 36 | dst[j++] = b[((a0 << 4) & 0x30) | ((a1 >> 4) & 0x0F)]; 37 | if (i < n - 1) 38 | dst[j++] = b[((a1 << 2) & 0x3C) | ((a2 >> 6) & 0x03)]; 39 | else 40 | dst[j++] = '='; 41 | if (i < n - 2) 42 | dst[j++] = b[a2 & 0x3F]; 43 | else 44 | dst[j++] = '='; 45 | } 46 | return j; 47 | } 48 | 49 | typedef struct md5_test { 50 | char* url; 51 | } md5_test; 52 | 53 | struct md5_test md5_tests[] = { 54 | { 55 | .url = "/home/tinyweb/www/1-63k_files/1k.txt", 56 | }, 57 | { 58 | .url = "/home/tinyweb/www/1-63k_files/2k.txt", 59 | }, 60 | { 61 | .url = "/home/tinyweb/www/1-63k_files/3k.txt", 62 | }, 63 | { 64 | .url = "/home/tinyweb/www/1-63k_files/4k.txt", 65 | }, 66 | { 67 | .url = "/home/tinyweb/www/1-63k_files/5k.txt", 68 | }, 69 | { 70 | .url = "/home/tinyweb/www/1-63k_files/6k.txt", 71 | }, 72 | { 73 | .url = "/home/tinyweb/www/1-63k_files/7k.txt", 74 | }, 75 | { 76 | .url = "/home/tinyweb/www/1-63k_files/8k.txt", 77 | }, 78 | { 79 | .url = "/home/tinyweb/www/1-63k_files/9k.txt", 80 | }, 81 | { 82 | .url = "/home/tinyweb/www/1-63k_files/10k.txt", 83 | }, 84 | }; 85 | 86 | void md5_check(char* str) 87 | { 88 | char res[32]; 89 | memset(res, 0, 32); 90 | md5(str, strlen(str), res); 91 | 92 | printf("%.*s\n", 32, res); 93 | } 94 | 95 | int test1() 96 | { 97 | unsigned int all = 0; 98 | unsigned int pass = 0; 99 | 100 | unsigned int len = 10; 101 | 102 | for (unsigned int i = 0; i < len; i++) { 103 | md5_check(md5_tests[i].url); 104 | } 105 | } 106 | 107 | int main() 108 | { 109 | test1(); 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /src/test/messagequeue_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 24 | 25 | mqd_t mqd; 26 | 27 | void create() 28 | { 29 | 30 | int c, flags; 31 | 32 | flags = O_RDWR | O_CREAT | O_EXCL; 33 | // /dev/mqueue/ 34 | mqd = mq_open("/mq123", flags, FILE_MODE, NULL); 35 | if (mqd == -1) 36 | { 37 | handle_error("mq_open error:"); 38 | } 39 | 40 | mq_close(mqd); 41 | } 42 | 43 | void remove() 44 | { 45 | mq_unlink("/mq123"); 46 | } 47 | 48 | void send() 49 | { 50 | 51 | mqd_t mqd; 52 | char ptr[] = "abc"; 53 | size_t len; 54 | unsigned prio; 55 | 56 | len = 3; 57 | prio = 1; 58 | mqd = mq_open("/mq123", O_WRONLY); 59 | 60 | mq_send(mqd, (const char *)ptr, len, prio); 61 | } 62 | 63 | void recv() 64 | { 65 | 66 | mqd_t mqd; 67 | void *ptr; 68 | size_t len; 69 | unsigned prio; 70 | 71 | len = 3; 72 | prio = 1; 73 | mqd = mq_open("/mq123", O_RDONLY); 74 | 75 | struct mq_attr attr; 76 | mq_getattr(mqd, &attr); 77 | ptr = malloc(attr.mq_msgsize); 78 | 79 | mq_receive(mqd, (char *)ptr, attr.mq_msgsize, &prio); 80 | std::cout << (char *)ptr << std::endl; 81 | } 82 | 83 | int main(int argc, char **argv) 84 | { 85 | using namespace std; 86 | int i; 87 | cin >> i; 88 | 89 | if (i == 1) 90 | { 91 | create(); 92 | } 93 | else if (i == 2) 94 | { 95 | remove(); 96 | } 97 | else if (i == 3) 98 | { 99 | send(); 100 | } 101 | else if (i == 4) 102 | { 103 | recv(); 104 | } 105 | 106 | return 0; 107 | } -------------------------------------------------------------------------------- /src/test/mutex_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/test/process_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | using namespace std; 20 | 21 | int main() 22 | { 23 | Socket * listenSocket = new Socket(createNoBlockSocket()); 24 | NetAddress listenAddress(9090); 25 | listenSocket->bindAddress(listenAddress); 26 | 27 | int listenFd = listenSocket->getFd(); 28 | int socketPairFds[2] = { -1, -1 }; 29 | int index = 1; 30 | Process* proc = new Process(std::to_string(index), index, socketPairFds); 31 | proc->setSignalHandlers(); 32 | proc->createListenServer(listenFd); 33 | proc->start(); 34 | 35 | delete proc; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /src/test/processpool_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | using namespace std; 20 | 21 | void initConfiger() 22 | { 23 | std::string file = "../../tmp_TinyWeb.conf"; 24 | Configer& configer = Configer::getConfigerInstance(); 25 | 26 | if (0 == configer.checkConfigerFile(file)) { 27 | std::cout << "file valid" << std::endl; 28 | configer.setConfigerFile(file); 29 | } else { 30 | std::cout << "file invalid" << std::endl; 31 | return; 32 | } 33 | 34 | bool debug = true; 35 | if (0 == configer.loadConfig(debug)) 36 | std::cout << "++load config successfull\n"; 37 | else 38 | std::cout << "--load config failed\n"; 39 | std::cout << std::endl; 40 | } 41 | 42 | int main() 43 | { 44 | initConfiger(); 45 | { 46 | std::string loglevel = "Debug"; 47 | std::string logpath = "/home/tinyweb/log/"; 48 | std::string debugfile = logpath + "debug.log"; 49 | std::string infofile = logpath + "info.log"; 50 | std::string warnfile = logpath + "warn.log"; 51 | std::string errorfile = logpath + "error.log"; 52 | std::string fatalfile = logpath + "fatal.log"; 53 | initLogger(debugfile, 54 | infofile, 55 | warnfile, 56 | errorfile, 57 | fatalfile, 58 | convertStringToLoglevel(loglevel)); //error used 59 | setLogLevel(Debug); 60 | 61 | std::cout << "[Process Pool Test]" << std::endl; 62 | ProcessPool pool; 63 | pool.init(); 64 | pool.createProcess(4); 65 | 66 | pool.start(); 67 | } 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /src/test/protocol_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | 26 | 27 | int main() 28 | { 29 | const Protocol *p1, *p2, *p3, *p4; 30 | p1 = new Protocol; 31 | p2 = new DiscardProtocol; 32 | p3 = new EchoProtocol; 33 | p4 = new WebProtocol; 34 | 35 | cout << typeid(*p1).name() << endl; 36 | cout << typeid(*p2).name() << endl; 37 | cout << typeid(*p3).name() << endl; 38 | cout << typeid(*p4).name() << endl; 39 | 40 | Protocol *p5, *p6, *p7, *p8; 41 | // p5 = Reflect::getReflectInstance().getProtocolByName(getName(p1)); 42 | // p6 = Reflect::getReflectInstance().getProtocolByName(getName(p2)); 43 | // p7 = Reflect::getReflectInstance().getProtocolByName(getName(p3)); 44 | // p8 = Reflect::getReflectInstance().getProtocolByName(getName(p4)); 45 | 46 | p5 = getInstanceByPointer(p1); 47 | p6 = getInstanceByPointer(p2); 48 | p7 = getInstanceByPointer(p3); 49 | p8 = getInstanceByPointer(p4); 50 | 51 | cout << typeid(*p5).name() << endl; 52 | cout << typeid(*p6).name() << endl; 53 | cout << typeid(*p7).name() << endl; 54 | cout << typeid(*p8).name() << endl; 55 | 56 | delete p1; 57 | delete p2; 58 | delete p3; 59 | delete p4; 60 | 61 | delete p5; 62 | delete p6; 63 | delete p7; 64 | delete p8; 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /src/test/rbtree_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | 8 | { 9 | int n; 10 | cin >> n; 11 | cout << "---------" << n << endl; 12 | RbTree tree; 13 | std::cout << sizeof(tree) << std::endl; 14 | for (int i = 0; i < n; i++) 15 | tree.insert(i); 16 | tree.PrintTreeLevel(); 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /src/test/reader_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | 21 | int main() 22 | { 23 | const std::string file = "../TinyWeb.conf"; 24 | Reader reader(file); 25 | cout << "line number:" << reader.getLineNu() << endl; 26 | 27 | while (reader.haveMore()) 28 | { 29 | cout << reader.getCurrLineNu() << ":" << reader.readLine(); 30 | } 31 | 32 | cout << "reader again\n"; 33 | reader.resetToHead(); 34 | 35 | while (reader.haveMore()) 36 | { 37 | cout << reader.getCurrLineNu() << ":" << reader.readLine(); 38 | } 39 | //------------------------------------// 40 | cout << "change reader file\n"; 41 | reader.setFile(file); 42 | 43 | cout << "line number:" << reader.getLineNu() << endl; 44 | 45 | while (reader.haveMore()) 46 | { 47 | cout << reader.getCurrLineNu() << ":" << reader.readLine(); 48 | } 49 | 50 | cout << "reader again\n"; 51 | reader.resetToHead(); 52 | 53 | while (reader.haveMore()) 54 | { 55 | cout << reader.getCurrLineNu() << ":" << reader.readLine(); 56 | } 57 | } -------------------------------------------------------------------------------- /src/test/regex.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeneralSandman/TinyWeb/a381da252fe8e873c8aff22703040426cc9b2ae0/src/test/regex.py -------------------------------------------------------------------------------- /src/test/semaphore_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/test/sharedmemory_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | typedef struct 24 | { 25 | SharedMemory* memory; 26 | Semaphore* sem; 27 | } sync_t; 28 | 29 | sync_t test1; 30 | 31 | void consumer() 32 | { 33 | int* data; 34 | std::string str; 35 | for (int i = 0; i < 1; i++) { 36 | test1.sem->lock(); 37 | data = (int*)test1.memory->getSpace(); 38 | std::cout << "consumer:" << *data << std::endl; 39 | test1.sem->unLock(); 40 | } 41 | } 42 | 43 | void productor() 44 | { 45 | int* data; 46 | std::string str; 47 | for (int i = 0; i < 200000; i++) { 48 | test1.sem->lock(); 49 | data = (int*)test1.memory->getSpace(); 50 | *data = *data + 1; 51 | std::cout << "[" << getpid() << "]write:" << *data << std::endl; 52 | test1.sem->unLock(); 53 | } 54 | } 55 | 56 | #include 57 | 58 | int main() 59 | { 60 | 61 | SharedMemory* sem_memory = new SharedMemory(sizeof(sem_t)); 62 | test1.sem = new Semaphore(sem_memory, 1); 63 | test1.memory = new SharedMemory(sizeof(int)); 64 | 65 | int* data = (int*)test1.memory->getSpace(); 66 | *data = 0; 67 | 68 | pid_t pid; 69 | 70 | pid = fork(); 71 | if (pid < 0) { 72 | std::cout << "fork error" << std::endl; 73 | return -1; 74 | } else if (pid == 0) { 75 | sleep(15); 76 | consumer(); 77 | } else { 78 | 79 | pid = fork(); 80 | if (pid < 0) { 81 | std::cout << "fork2 error" << std::endl; 82 | return -1; 83 | } else if (pid == 0) { 84 | productor(); 85 | } else { 86 | productor(); 87 | } 88 | } 89 | std::cout << "exit" << std::endl; 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /src/test/socketpair_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | using namespace std; 27 | 28 | void getMessage(Connection *con, Buffer *buf, Time time) 29 | { 30 | std::cout << "receve data:" << buf->getAll() << std::endl; 31 | } 32 | 33 | void print() 34 | { 35 | // std::cout << getpid() << "--\n"; 36 | } 37 | 38 | void parent() 39 | { 40 | } 41 | 42 | void child() 43 | { 44 | } 45 | 46 | int main() 47 | { 48 | int sockpairFds[2]; 49 | int res = socketpair(AF_UNIX, SOCK_STREAM, 0, sockpairFds); 50 | if (res == -1) 51 | handle_error("socketpair error:"); 52 | 53 | pid_t pid = fork(); 54 | if (pid < 0) 55 | { 56 | cout << "error\n"; 57 | } 58 | else if (pid == 0) 59 | { 60 | EventLoop *loop = new EventLoop(); 61 | SocketPair pipe(loop, sockpairFds); 62 | pipe.setChildSocket(); 63 | pipe.setMessageCallback(boost::bind(&getMessage, _1, _2, _3)); 64 | 65 | TimerId id1 = loop->runEvery(1, boost::bind(&SocketPair::writeToParent, &pipe, "bb")); 66 | TimerId id2 = loop->runAfter(10, boost::bind(&EventLoop::quit, loop)); 67 | loop->loop(); 68 | 69 | pipe.clearSocket(); 70 | delete loop; 71 | } 72 | else 73 | { 74 | EventLoop *loop = new EventLoop(); 75 | SocketPair pipe(loop, sockpairFds); 76 | pipe.setParentSocket(); 77 | pipe.setMessageCallback(boost::bind(&getMessage, _1, _2, _3)); 78 | 79 | TimerId id1 = loop->runEvery(1, boost::bind(&SocketPair::writeToChild, &pipe, "aa")); 80 | TimerId id2 = loop->runAfter(10, boost::bind(&EventLoop::quit, loop)); 81 | loop->loop(); 82 | 83 | pipe.clearSocket(); 84 | delete loop; 85 | } 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /src/test/sync_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | using namespace std; 23 | 24 | void consumer(Sync* sync) 25 | { 26 | int* data; 27 | std::string str; 28 | for (int i = 0; i < 1; i++) { 29 | sync->sem->lock(); 30 | data = (int*)sync->memory->getSpace(); 31 | std::cout << "consumer:" << *data << std::endl; 32 | sync->sem->unLock(); 33 | } 34 | } 35 | 36 | void productor(Sync* sync) 37 | { 38 | int* data; 39 | std::string str; 40 | for (int i = 0; i < 200000; i++) { 41 | sync->sem->lock(); 42 | data = (int*)sync->memory->getSpace(); 43 | *data = *data + 1; 44 | // std::cout << "[" << getpid() << "]write:" << *data << std::endl; 45 | sync->sem->unLock(); 46 | } 47 | } 48 | 49 | int main() 50 | { 51 | shared_ptr sync = std::make_shared(sizeof(int)); 52 | 53 | int* data = (int*)sync->memory->getSpace(); 54 | *data = 0; 55 | 56 | pid_t pid; 57 | pid = fork(); 58 | if (pid < 0) { 59 | std::cout << "fork error" << std::endl; 60 | return -1; 61 | } else if (pid == 0) { 62 | sleep(7); 63 | consumer(sync.get()); 64 | } else { 65 | 66 | pid = fork(); 67 | if (pid < 0) { 68 | std::cout << "fork2 error" << std::endl; 69 | return -1; 70 | } else if (pid == 0) { 71 | productor(sync.get()); 72 | } else { 73 | pid = fork(); 74 | if (pid < 0) { 75 | std::cout << "fork3 error" << std::endl; 76 | return -1; 77 | } else if (pid == 0) { 78 | productor(sync.get()); 79 | } else { 80 | productor(sync.get()); 81 | } 82 | } 83 | } 84 | std::cout << "exit" << std::endl; 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /src/test/test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static int 13 | checkForZeroes(char* buf, int n) 14 | { 15 | int i, j; 16 | unsigned long* lbuf = (unsigned long*)buf; 17 | assert(n % sizeof(unsigned long) == 0); 18 | 19 | for (i = 0; i * sizeof(unsigned long) < n; i++) { 20 | if (lbuf[i] != 0L) 21 | return i * sizeof(unsigned long); 22 | } 23 | for (j = 0; i * sizeof(unsigned long) + j < n; j++) { 24 | if (buf[i * sizeof(unsigned long) + j] != 0) 25 | break; 26 | } 27 | 28 | return i * sizeof(unsigned long) + j; 29 | } 30 | 31 | int main1() 32 | { 33 | char* buf = ""; 34 | int nread = strlen(buf); 35 | int nzeroes = checkForZeroes(buf, nread & -8); 36 | 37 | std::cout << "nzeors:" << nzeroes << std::endl; 38 | 39 | return 0; 40 | } 41 | 42 | typedef struct header { 43 | int a; 44 | int b; 45 | 46 | } header; 47 | 48 | #include 49 | #include 50 | 51 | typedef boost::function Callback1; 52 | typedef boost::function Callback2; 53 | 54 | void print_header(header* h) 55 | { 56 | if (nullptr == h) { 57 | return; 58 | } 59 | std::cout << "header a:" << h->a << ",b:" << h->b << std::endl; 60 | }; 61 | 62 | int main() 63 | { 64 | header* h1 = new header; 65 | h1->a = 1; 66 | h1->b = 1; 67 | 68 | header* h2 = new header; 69 | h2->a = 2; 70 | h2->b = 2; 71 | 72 | Callback2 func = boost::bind(print_header, h1); 73 | func(); 74 | 75 | func = boost::bind(print_header, h2); 76 | func(); 77 | 78 | auto print_header2 = [h1]() 79 | { 80 | if (nullptr == h1) { 81 | return; 82 | } 83 | std::cout << "header a:" << h1->a << ",b:" << h1->b << std::endl; 84 | }; 85 | 86 | func = print_header2; 87 | func(); 88 | 89 | delete h1; 90 | delete h2; 91 | } 92 | -------------------------------------------------------------------------------- /src/test/thread_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | void threadFunc() 24 | { 25 | printf("tid=%d\n", CurrentThread::tid()); 26 | } 27 | 28 | void threadFunc2(int x) 29 | { 30 | printf("tid=%d, x=%d\n", CurrentThread::tid(), x); 31 | } 32 | 33 | class Foo 34 | { 35 | public: 36 | explicit Foo(double x) 37 | : x_(x) 38 | { 39 | } 40 | 41 | void memberFunc() 42 | { 43 | printf("tid=%d, Foo::x_=%f\n", CurrentThread::tid(), x_); 44 | } 45 | 46 | void memberFunc2(const std::string &text) 47 | { 48 | printf("tid=%d, Foo::x_=%f, text=%s\n", CurrentThread::tid(), x_, text.c_str()); 49 | } 50 | 51 | private: 52 | double x_; 53 | }; 54 | 55 | int main() 56 | { 57 | printf("pid=%d, tid=%d\n", ::getpid(), CurrentThread::tid()); 58 | 59 | Thread t1(threadFunc, "t1"); 60 | t1.start(); 61 | t1.join(); 62 | //------- 63 | 64 | Thread t2(boost::bind(threadFunc2, 42), 65 | "thread for free function with argument"); 66 | t2.start(); 67 | t2.join(); 68 | //------- 69 | 70 | Foo foo(87.53); 71 | Thread t3(boost::bind(&Foo::memberFunc, &foo), 72 | "thread for member function without argument"); 73 | t3.start(); 74 | t3.join(); 75 | //------- 76 | 77 | Thread t4(boost::bind(&Foo::memberFunc2, boost::ref(foo), std::string("Thread"))); 78 | t4.start(); 79 | t4.join(); 80 | 81 | printf("number of created threads %d\n", Thread::numCreated()); 82 | 83 | return 0; 84 | } -------------------------------------------------------------------------------- /src/test/threadpool_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | void print() 23 | { 24 | printf("tid=%d\n", CurrentThread::tid()); 25 | } 26 | 27 | void printString(const std::string &str) 28 | { 29 | printf("tid=%d, str=%s\n", CurrentThread::tid(), str.c_str()); 30 | } 31 | 32 | int main() 33 | { 34 | printf("pid=%d, tid=%d\n", ::getpid(), CurrentThread::tid()); 35 | 36 | ThreadPool pool("MainThreadPool"); 37 | pool.start(4); 38 | 39 | pool.run(print); 40 | pool.run(print); 41 | for (int i = 0; i < 100; ++i) 42 | { 43 | char buf[32]; 44 | snprintf(buf, sizeof buf, "task %d", i); 45 | pool.run(boost::bind(printString, std::string(buf))); 46 | } 47 | 48 | // CountDownLatch latch(1); 49 | // pool.run(boost::bind(& CountDownLatch::countDown, &latch)); 50 | // latch.wait(); 51 | sleep(1); 52 | pool.stop(); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /src/test/time_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | int main() 23 | { 24 | Time now(Time::now()); 25 | printf("%s\n", now.toString().c_str()); 26 | std::cout << now.toFormattedString() << std::endl; 27 | } 28 | -------------------------------------------------------------------------------- /src/test/timerqueue_test.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | EventLoop *g_loop = nullptr; 24 | 25 | int global_num1 = 0; 26 | int global_num2 = 0; 27 | 28 | TimerId timerid1, timerid2; 29 | 30 | void fun1() 31 | { 32 | cout << "[Timer1]:cout per second\n"; 33 | global_num1++; 34 | if (global_num1 == 10) 35 | { 36 | cout << "[Timer1]:cancel Timer1\n"; 37 | g_loop->cancelTimerId(timerid1); 38 | } 39 | } 40 | 41 | void fun2() 42 | { 43 | cout << "[Timer2]:cout per two second\n"; 44 | global_num2++; 45 | if (global_num2 == 5) 46 | { 47 | cout << "[Timer2]:cancel Timer2\n"; 48 | g_loop->cancelTimerId(timerid2); 49 | } 50 | } 51 | 52 | void timeout() 53 | { 54 | cout << "[Timer3]:13 seconds from main function started\n"; 55 | cout << "[Timer3]:quit eventloop\n"; 56 | g_loop->quit(); 57 | } 58 | 59 | int main() 60 | { 61 | g_loop = new EventLoop(); 62 | timerid1 = g_loop->runEvery(1, boost::bind(fun1)); 63 | timerid2 = g_loop->runEvery(2, boost::bind(fun2)); 64 | 65 | if (timerid1.isVaild()) 66 | std::cout << "timerid1 vaild\n"; 67 | else 68 | std::cout << "timerid1 invaild\n"; 69 | 70 | if (timerid2.isVaild()) 71 | std::cout << "timerid2 vaild\n"; 72 | else 73 | std::cout << "timerid2 invaild\n"; 74 | 75 | std::cout << "after cancel timerid1 and timerid2\n"; 76 | g_loop->cancelTimerId(timerid1); 77 | g_loop->cancelTimerId(timerid2); 78 | 79 | if (timerid1.isVaild()) 80 | std::cout << "timerid1 vaild\n"; 81 | else 82 | std::cout << "timerid1 invaild\n"; 83 | 84 | if (timerid2.isVaild()) 85 | std::cout << "timerid2 vaild\n"; 86 | else 87 | std::cout << "timerid2 invaild\n"; 88 | 89 | g_loop->runAfter(13, boost::bind(timeout)); 90 | 91 | g_loop->loop(); 92 | delete g_loop; 93 | return 0; 94 | } -------------------------------------------------------------------------------- /src/tiny_base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #tiny_base/CMakeLists.txt 2 | 3 | cmake_minimum_required(VERSION 2.8) 4 | 5 | add_definitions("-Wall -std=c++11") 6 | 7 | add_library(tiny_base_model STATIC 8 | api.cc 9 | buffer.cc 10 | condition.cc 11 | configer.cc 12 | exception.cc 13 | list_timer.cc 14 | log.cc 15 | file.cc 16 | memorypool.cc 17 | messagequeue.cc 18 | semaphore.cc 19 | sharedmemory.cc 20 | signalmanager.cc 21 | md5.cc 22 | ) 23 | -------------------------------------------------------------------------------- /src/tiny_base/atomic.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---Configer Class--- 9 | *We need to upgrade this class 10 | *in order to handle config file error 11 | **************************************** 12 | * 13 | */ 14 | 15 | #ifndef ATOMIC_H 16 | #define ATOMIC_H 17 | 18 | #include 19 | #include 20 | 21 | template 22 | class AtomicIntegerT : boost::noncopyable { 23 | public: 24 | AtomicIntegerT() : 25 | value_(0) { 26 | } 27 | 28 | // uncomment if you need copying and assignment 29 | // 30 | // AtomicIntegerT(const AtomicIntegerT& that) 31 | // : value_(that.get()) 32 | // {} 33 | // 34 | // AtomicIntegerT& operator=(const AtomicIntegerT& that) 35 | // { 36 | // getAndSet(that.get()); 37 | // return *this; 38 | // } 39 | 40 | T get() { 41 | return __sync_val_compare_and_swap(&value_, 0, 0); 42 | } 43 | 44 | T getAndAdd(T x) { 45 | return __sync_fetch_and_add(&value_, x); 46 | } 47 | 48 | T addAndGet(T x) { 49 | return getAndAdd(x) + x; 50 | } 51 | 52 | T incrementAndGet() { 53 | return addAndGet(1); 54 | } 55 | 56 | T decrementAndGet() { 57 | return addAndGet(-1); 58 | } 59 | 60 | void add(T x) { 61 | getAndAdd(x); 62 | } 63 | 64 | void increment() { 65 | incrementAndGet(); 66 | } 67 | 68 | void decrement() { 69 | decrementAndGet(); 70 | } 71 | 72 | T getAndSet(T newValue) { 73 | return __sync_lock_test_and_set(&value_, newValue); 74 | } 75 | 76 | private: 77 | volatile T value_; 78 | }; 79 | 80 | typedef AtomicIntegerT AtomicInt32; 81 | typedef AtomicIntegerT AtomicInt64; 82 | 83 | #endif // MUDUO_BASE_ATOMIC_H 84 | -------------------------------------------------------------------------------- /src/tiny_base/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | /*---class Buffer--- 15 | *It is very improtant to provied a network buffer to 16 | *socket, 17 | **************************************** 18 | * 19 | *put(fd):read date from fd and store into vector 20 | *get():fetch readable date 21 | */ 22 | 23 | #ifndef BUFFER_H 24 | #define BUFFER_H 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #define K_Buffer_Prepend 8 31 | #define K_Buffer_Size 1024 32 | const char kCRLF[] = "\r\n"; 33 | 34 | class Buffer { 35 | private: 36 | std::vector m_nDatas; 37 | int m_nReadIndex; 38 | int m_nWriteIndex; 39 | 40 | size_t m_fPrependableBytes() const; 41 | size_t m_fReadableBytes() const; 42 | size_t m_fWriteableBytes() const; 43 | char* m_fBegin(); 44 | const char* m_fBegin() const; 45 | char* m_fReadableBegin(); 46 | const char* m_fReadableBegin() const; 47 | char* m_fWriteableBegin(); 48 | const char* m_fWriteableBegin() const; 49 | void hasReadBytes(size_t len); 50 | void m_fEnsureWritableBytes(size_t len); 51 | void m_fMakeSpace(size_t len); 52 | void m_fClearAll(); 53 | 54 | public: 55 | Buffer(); 56 | void swap(Buffer& r); 57 | size_t put(int fd); 58 | size_t readableBytes() { 59 | return m_fReadableBytes(); 60 | } 61 | std::string get(size_t len); 62 | std::string getAll(); 63 | void shrink(); 64 | void append(const std::string& str); 65 | void append(const char* str, int len); 66 | void prepend(const void* /*restrict*/ data, size_t len); 67 | const char* findCRLF() const; 68 | const char* findCRLF(const char* start) const; 69 | bool getALine(std::string& res); 70 | ~Buffer(); 71 | }; 72 | 73 | #endif // !BUFFER_H 74 | -------------------------------------------------------------------------------- /src/tiny_base/condition.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | -------------------------------------------------------------------------------- /src/tiny_base/condition.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---Configer Class--- 9 | *We need to upgrade this class 10 | *in order to handle config file error 11 | **************************************** 12 | * 13 | */ 14 | 15 | #ifndef CONDITION_H 16 | #define CONDITION_H 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | class Condition : boost::noncopyable { 25 | private: 26 | MutexLock& m_nMutexLock; 27 | pthread_cond_t m_nCond; 28 | 29 | public: 30 | explicit Condition(MutexLock& mutex) : 31 | m_nMutexLock(mutex) { 32 | int res = pthread_cond_init(&m_nCond, NULL); 33 | if (res != 0) 34 | handle_error("pthread_cond_init() error"); 35 | } 36 | void wait() { 37 | pthread_cond_wait(&m_nCond, 38 | m_nMutexLock.getPthreadMutex()); 39 | } 40 | bool waitForSeconds(int second) { 41 | // if time out return true, 42 | struct timespec abs; 43 | clock_gettime(CLOCK_REALTIME, &abs); 44 | abs.tv_sec += second; 45 | return ETIMEDOUT == pthread_cond_timedwait(&m_nCond, m_nMutexLock.getPthreadMutex(), &abs); 46 | } 47 | void notify() { 48 | pthread_cond_signal(&m_nCond); 49 | } 50 | void notifyAll() { 51 | pthread_cond_broadcast(&m_nCond); 52 | } 53 | ~Condition() { 54 | int res = pthread_cond_destroy(&m_nCond); 55 | if (res != 0) 56 | handle_error("pthread_cond_destroy() error"); 57 | } 58 | }; 59 | 60 | #endif -------------------------------------------------------------------------------- /src/tiny_base/exception.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | 12 | Exception::Exception(const char* msg) : 13 | m_nName(msg) { 14 | m_fFillStackTrace(); 15 | } 16 | 17 | Exception::Exception(const std::string& msg) : 18 | m_nName(msg) { 19 | m_fFillStackTrace(); 20 | } 21 | 22 | Exception::Exception(const Exception& e) { 23 | m_nName = e.m_nName; 24 | m_nStack = e.m_nStack; 25 | } 26 | 27 | void Exception::m_fFillStackTrace() { 28 | int size = 200; 29 | void* buffer[size]; 30 | int nptrs = backtrace(buffer, size); 31 | char** str = backtrace_symbols(buffer, nptrs); 32 | if (str) { 33 | for (int i = 0; i < nptrs; i++) { 34 | m_nStack += str[i]; 35 | m_nStack += '\n'; 36 | } 37 | } 38 | free(str); 39 | } -------------------------------------------------------------------------------- /src/tiny_base/exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---class Exception--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef EXCEPTION_H 15 | #define EXCEPTION_H 16 | 17 | #include 18 | #include 19 | 20 | class Exception { 21 | private: 22 | std::string m_nName; 23 | std::string m_nStack; 24 | void m_fFillStackTrace(); 25 | 26 | public: 27 | explicit Exception(const char* msg); 28 | explicit Exception(const std::string& msg); 29 | Exception(const Exception&); 30 | const std::string& what() throw() { 31 | return m_nName; 32 | } 33 | // const char *what()throw(){return m_nName.c_str();}; 34 | const std::string& stackTrace() throw() { 35 | return m_nStack; 36 | } 37 | // const char* stackTrace()throw(){return m_nStack.c_str();} 38 | virtual ~Exception() throw() { 39 | } 40 | }; 41 | 42 | #endif -------------------------------------------------------------------------------- /src/tiny_base/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef FILE_H 15 | #define FILE_H 16 | 17 | #include 18 | 19 | #include 20 | 21 | int isRegularFile(const std::string& fname); 22 | std::string getType(const std::string& f); 23 | 24 | class File { 25 | public: 26 | std::string name; 27 | std::string type; 28 | bool valid; 29 | int fd; 30 | off_t offset; 31 | struct stat info; 32 | 33 | // appendData only used by getData(), 34 | // It append data begin dest and 35 | // Return the end of chain. 36 | unsigned int appendData(chain_t*& dest, const char* data, unsigned int len); 37 | 38 | public: 39 | File() : 40 | valid(false), fd(-1), offset(0) { 41 | memset((void*)&info, 0, sizeof(info)); 42 | } 43 | 44 | int setFile(const std::string& fname); 45 | inline unsigned int getFileSize() { 46 | if (valid) { 47 | return info.st_size; 48 | } 49 | return 0; 50 | } 51 | inline bool noMoreData() { 52 | if (valid) { 53 | // std::cout << "noMoreData:offset(" << offset << "),file-size(" << info.st_size << ")\n"; 54 | return (offset == info.st_size); 55 | } else { 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | void getData(chain_t* chain); 62 | // using for Range && Content-Range. 63 | void getData(chain_t* chain, off_t begin, off_t end); 64 | 65 | int writeData(chain_t* chain); 66 | 67 | ~File() { 68 | if (valid) { 69 | close(fd); 70 | } 71 | } 72 | }; 73 | 74 | #endif // !FILE_H 75 | -------------------------------------------------------------------------------- /src/tiny_base/list_timer.h: -------------------------------------------------------------------------------- 1 | #ifndef LISTTIMER_H 2 | #define LISTTIMER_H 3 | #include 4 | namespace timer { 5 | 6 | class ListTimer { 7 | public: 8 | time_t m_nTime; 9 | void (*m_fTimerHandler)(int); 10 | 11 | ListTimer* m_pNext; 12 | ListTimer* m_pPrev; 13 | 14 | public: 15 | ListTimer(ListTimer* n = nullptr, 16 | ListTimer* p = nullptr) : 17 | m_pNext(n), 18 | m_pPrev(p) { 19 | } 20 | ~ListTimer() { 21 | } 22 | }; 23 | class ListTimerManager { 24 | private: 25 | ListTimer* m_pHead; 26 | ListTimer* m_pTail; 27 | int m_fAddTimer(ListTimer*); 28 | int m_fDeleteTimer(ListTimer*); 29 | int m_fAdjustTimer(ListTimer*); 30 | 31 | public: 32 | ListTimerManager() : 33 | m_pHead(nullptr), 34 | m_pTail(nullptr) { 35 | } 36 | ~ListTimerManager(); 37 | 38 | void addTimer(ListTimer*); 39 | void deleteTimer(ListTimer*); 40 | void heatBeat(int); 41 | }; 42 | } // namespace timer 43 | 44 | #endif -------------------------------------------------------------------------------- /src/tiny_base/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef TINY_MD5_H 15 | #define TINY_MD5_H 16 | 17 | #ifdef HAS_STDINT_H 18 | #include 19 | #elif defined(HAS_INTTYPES_H) 20 | #include 21 | #endif 22 | 23 | /* typedef a 32-bit type */ 24 | typedef unsigned int UINT4; 25 | 26 | /* Data structure for MD5 (Message-Digest) computation */ 27 | typedef struct MD5_CTX { 28 | UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ 29 | UINT4 buf[4]; /* scratch buffer */ 30 | unsigned char in[64]; /* input buffer */ 31 | unsigned char digest[16]; /* actual digest after MD5Final call */ 32 | } MD5_CTX; 33 | 34 | void MD5Init(MD5_CTX* mdContext); 35 | void MD5Update(MD5_CTX*, unsigned const char*, unsigned int); 36 | void MD5Final(MD5_CTX*); 37 | 38 | void md5(const char* key, int len, char* dst); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/tiny_base/messagequeue.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | MessageQueue::MessageQueue() { 17 | } 18 | void MessageQueue::notify() { 19 | } 20 | void MessageQueue::notify_all() { 21 | } 22 | 23 | void MessageQueue::wait() { 24 | } 25 | void MessageQueue::recev() { 26 | } 27 | void MessageQueue::send() { 28 | } 29 | MessageQueue::~MessageQueue() { 30 | } -------------------------------------------------------------------------------- /src/tiny_base/messagequeue.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef MESSAGE_QUEUE_H 15 | #define MESSAGE_QUEUE_H 16 | 17 | #include 18 | 19 | class MessageQueue { 20 | private: 21 | mqd_t m_nMQFd; 22 | 23 | public: 24 | MessageQueue(); 25 | void notify(); 26 | void notify_all(); 27 | void wait(); 28 | 29 | void recev(); 30 | void send(); 31 | ~MessageQueue(); 32 | }; 33 | 34 | #endif -------------------------------------------------------------------------------- /src/tiny_base/mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef __MUTEX_H 15 | #define __MUTEX_H 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | class MutexLock : boost::noncopyable { 23 | private: 24 | pthread_mutex_t m_nMutex; 25 | pid_t m_nHolder; 26 | 27 | public: 28 | MutexLock() { 29 | m_nHolder = 0; 30 | int res = pthread_mutex_init(&m_nMutex, NULL); 31 | if (res != 0) 32 | handle_error("pthread_mutex_init() error"); 33 | } 34 | void lock() { 35 | pthread_mutex_lock(&m_nMutex); 36 | // m_nHolder=currtid; 37 | // don't finished 38 | } 39 | void unlock() { 40 | m_nHolder = 0; 41 | pthread_mutex_unlock(&m_nMutex); 42 | } 43 | bool isLockByThisThread() { 44 | // return m_nHolder==currtid; 45 | // don't finished 46 | return true; 47 | } 48 | pthread_mutex_t* getPthreadMutex() { 49 | return &m_nMutex; 50 | } 51 | ~MutexLock() { 52 | // at this time,m_nHolder==0, 53 | int res = pthread_mutex_destroy(&m_nMutex); 54 | if (res != 0) 55 | handle_error("pthread_mutex_destroy() error"); 56 | } 57 | }; 58 | 59 | class MutexLockGuard : boost::noncopyable { 60 | private: 61 | MutexLock& m_nMutexLock; 62 | // but the muduo is the reference,why? 63 | // MutexLock& mutex_; 64 | public: 65 | explicit MutexLockGuard(MutexLock& mutex) : 66 | m_nMutexLock(mutex) { 67 | m_nMutexLock.lock(); 68 | } 69 | ~MutexLockGuard() { 70 | m_nMutexLock.unlock(); 71 | } 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/tiny_base/new_buffer.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | -------------------------------------------------------------------------------- /src/tiny_base/new_buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef NEW_BUFFER_H 15 | #define NEW_BUFFER_H 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #define K_Buffer_Prepend 8 23 | #define K_Buffer_Size 1024 24 | const char kCRLF[] = "\r\n"; 25 | 26 | class NewBuffer { 27 | private: 28 | chain_t* m_nDatas; 29 | 30 | public: 31 | NewBuffer(); 32 | 33 | ~NewBuffer(); 34 | }; 35 | 36 | #endif // !NEW_BUFFER_H 37 | -------------------------------------------------------------------------------- /src/tiny_base/reader.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | void Reader::m_fInit(void) { 18 | m_nFileStream.open(m_nFile, std::ios_base::in); 19 | if (m_nFileStream.fail()) 20 | handle_error("fail not exists"); 21 | m_nLine = 0; 22 | m_nCurrLine = 0; 23 | m_fCountLine(); 24 | } 25 | 26 | void Reader::m_fCountLine(void) { 27 | std::string tmp; 28 | while (getline(m_nFileStream, tmp, '\n')) { 29 | m_nLine++; 30 | } 31 | m_nFileStream.clear(); 32 | m_nFileStream.seekg(0, std::ios::beg); 33 | } 34 | 35 | Reader::Reader(const std::string& file) { 36 | m_nFile = file; 37 | m_fInit(); 38 | // LOG(Debug) << "class Reader constructor\n"; 39 | } 40 | 41 | void Reader::setFile(const std::string& f) { 42 | m_nFile = f; 43 | m_nFileStream.close(); 44 | m_fInit(); 45 | } 46 | 47 | std::string Reader::readLine(void) { 48 | std::string result; 49 | getline(m_nFileStream, result, '\n'); 50 | result += '\n'; 51 | m_nCurrLine++; 52 | return result; 53 | } 54 | 55 | void Reader::resetToHead(void) { 56 | m_nFileStream.clear(); 57 | m_nFileStream.seekg(0, std::ios_base::beg); 58 | m_nCurrLine = 0; 59 | } 60 | 61 | Reader::~Reader() { 62 | m_nFileStream.close(); 63 | 64 | // LOG(Debug) << "class Reader destructor\n"; 65 | } 66 | -------------------------------------------------------------------------------- /src/tiny_base/reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---Reader Class--- 9 | *Reader is a class which is used to read file. 10 | *This class doesn't use IO(buffer)-class. 11 | *We need to upgrade this class. 12 | *Before we use readLine(),make sure invoke resetToHead() 13 | **************************************** 14 | *readLine(): 15 | * return current line content 16 | *getCurrLineNu(): 17 | * return current line number 18 | *haveMore(): 19 | * if file have more content to be readed,return true 20 | *resetToHead(): 21 | * reread begin the file head. 22 | */ 23 | 24 | #ifndef READER_H 25 | #define READER_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | class Reader { 32 | private: 33 | std::string m_nFile; 34 | std::ifstream m_nFileStream; 35 | int m_nLine; 36 | int m_nCurrLine; 37 | 38 | void m_fInit(void); 39 | void m_fCountLine(void); 40 | 41 | public: 42 | Reader(const std::string& f); 43 | void setFile(const std::string& f); 44 | std::string readLine(void); 45 | int getCurrLineNu(void) { 46 | return m_nCurrLine; 47 | } 48 | int getLineNu(void) { 49 | return m_nLine; 50 | } 51 | bool haveMore(void) { 52 | return m_nLine > m_nCurrLine; 53 | } 54 | void resetToHead(void); 55 | ~Reader(); 56 | }; 57 | 58 | #endif // !READER_H 59 | -------------------------------------------------------------------------------- /src/tiny_base/semaphore.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | Semaphore::Semaphore(SharedMemory* memory, int value) { 22 | m_nSem = (sem_t*)memory->getSpace(); 23 | sem_init(m_nSem, 1, value); // shared in multi-process. 24 | LOG(Debug) << "class Semaphore constructor\n"; 25 | } 26 | 27 | void Semaphore::lock() { 28 | int res; 29 | res = sem_wait(m_nSem); 30 | 31 | if (res == -1) { 32 | handle_error("sem_wait() error:"); 33 | } 34 | } 35 | 36 | void Semaphore::tryLock() { 37 | // FIXME: 38 | int res; 39 | res = sem_trywait(m_nSem); 40 | 41 | if (res == -1) { 42 | handle_error("sem_wait() error:"); 43 | } 44 | } 45 | 46 | void Semaphore::unLock() { 47 | int res; 48 | res = sem_post(m_nSem); 49 | 50 | if (res == -1) { 51 | handle_error("sem_wait() error:"); 52 | } 53 | } 54 | 55 | int Semaphore::getValue() { 56 | int res; 57 | sem_getvalue(m_nSem, &res); 58 | return res; 59 | } 60 | 61 | Semaphore::~Semaphore() { 62 | sem_destroy(m_nSem); 63 | LOG(Debug) << "class Semaphore destructor\n"; 64 | } 65 | -------------------------------------------------------------------------------- /src/tiny_base/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---class Semaphore--- 9 | * 10 | **************************************** 11 | * 12 | *Semaphore():create memory-based semaphore and initialize the value of 13 | semaphore to the pararm 14 | *wait():wait semaphore(wait if the value is less than or equal to 0,and 15 | * decrease the value the semaphore) 16 | *tryWait(): 17 | *post():post to a semaphore(increase the value of the semaphore) 18 | *getValue(): 19 | *~Semaphore():destory the semaphore 20 | */ 21 | 22 | #ifndef SEMAPHORE_H 23 | #define SEMAPHORE_H 24 | 25 | #include 26 | 27 | #include 28 | 29 | class Semaphore { 30 | private: 31 | sem_t* m_nSem; 32 | // sem_t must be stored in shared memory 33 | 34 | public: 35 | Semaphore(SharedMemory* memory, int value = 0); 36 | void lock(); 37 | void tryLock(); 38 | void unLock(); 39 | int getValue(); 40 | ~Semaphore(); 41 | }; 42 | 43 | #endif // !SEMAPHORE_H 44 | -------------------------------------------------------------------------------- /src/tiny_base/sharedmemory.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #if (SHARED_MEMORY_ANON) 19 | 20 | void* SharedMemory::shm_alloc(size_t size) { 21 | LOG(Debug) << "alloc shared-memory by mmap(anon)\n"; 22 | 23 | m_pSharedData = mmap(NULL, m_nSize, 24 | PROT_READ | PROT_WRITE, 25 | MAP_ANON | MAP_SHARED, -1, 0); 26 | if (m_pSharedData == MAP_FAILED) { 27 | handle_error("mmap error:"); 28 | return nullptr; 29 | } 30 | 31 | return m_pSharedData; 32 | } 33 | 34 | void SharedMemory::shm_free(void* data, size_t size) { 35 | LOG(Debug) << "free shared-memory by mmap(anon)\n"; 36 | 37 | if (0 != munmap(data, size)) 38 | handle_error("munmap error:"); 39 | } 40 | 41 | #elif (SHARED_MEMORY_DEVZERO) 42 | 43 | void* SharedMemory::shm_alloc(size_t size) { 44 | LOG(Debug) << "alloc shared-memory by mmap(dev/zero)\n"; 45 | 46 | return nullptr; 47 | } 48 | 49 | void SharedMemory::shm_free(void* data, size_t size) { 50 | LOG(Debug) << "free shared-memory by mmap(dev/zero)\n"; 51 | } 52 | 53 | #elif (SHARED_MEMORY_SYSVSHM) 54 | 55 | #include 56 | 57 | void* SharedMemory::shm_alloc(size_t size) { 58 | LOG(Debug) << "alloc shared-memory by shmget()\n"; 59 | 60 | int id; 61 | void* data; 62 | 63 | id = shmget(IPC_PRIVATE, size, (SHM_R | SHM_W | IPC_CREAT)); 64 | 65 | if (id == -1) { 66 | handle_error("shmget error:"); 67 | return nullptr; 68 | } 69 | 70 | std::cout << "shmget id:" << id << std::endl; 71 | 72 | data = shmat(id, NULL, 0); 73 | 74 | if (data == (void*)-1) { 75 | handle_error("shmat() failed error:"); 76 | } 77 | 78 | if (shmctl(id, IPC_RMID, NULL) == -1) { 79 | handle_error("shmctl(IPC_RMID) failed:"); 80 | } 81 | 82 | return data; 83 | } 84 | 85 | void SharedMemory::shm_free(void* data, size_t size) { 86 | LOG(Debug) << "free shared-memory by shmget()\n"; 87 | if (shmdt(data) == -1) { 88 | handle_error("shmdt() error:"); 89 | } 90 | } 91 | 92 | #endif 93 | 94 | SharedMemory::SharedMemory(size_t size) : 95 | m_nSize(size) { 96 | m_pSharedData = shm_alloc(size); 97 | LOG(Debug) << "class SharedMemory constructor\n"; 98 | } 99 | 100 | SharedMemory::~SharedMemory() { 101 | shm_free(m_pSharedData, m_nSize); 102 | LOG(Debug) << "class SharedMemory destructor\n"; 103 | } 104 | -------------------------------------------------------------------------------- /src/tiny_base/sharedmemory.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SHAREDMEMORY_H 15 | #define SHAREDMEMORY_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | class SharedMemory { 23 | private: 24 | void* m_pSharedData; 25 | size_t m_nSize; 26 | std::string m_nName; 27 | 28 | void* shm_alloc(size_t size); 29 | void shm_free(void* data, size_t size); 30 | 31 | public: 32 | SharedMemory(size_t size); 33 | void* getSpace() { 34 | return m_pSharedData; 35 | } 36 | ~SharedMemory(); 37 | }; 38 | 39 | #endif // !SHAREDMEMORY_H 40 | -------------------------------------------------------------------------------- /src/tiny_base/signalmanager.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | // #include 17 | #include 18 | #include 19 | 20 | Signal::Signal(int num, const std::string& name, const std::string& meaning, SignalCallback callback) : 21 | m_nNumber(num), 22 | m_nName(name), 23 | m_nMeaning(meaning), 24 | m_nCallback(callback) { 25 | // LOG(Debug) << "class Signal constructor\n"; 26 | } 27 | 28 | Signal::~Signal() { 29 | // LOG(Debug) << "class Signal destructor\n"; 30 | } 31 | 32 | SignalManager::SignalManager() : 33 | m_nNum(0) { 34 | LOG(Debug) << "class SignalManager constructor\n"; 35 | } 36 | 37 | void SignalManager::addSignal(const Signal& s) { 38 | add_signal(s.m_nNumber, s.m_nCallback); 39 | m_nNum++; 40 | } 41 | 42 | void SignalManager::updateSignal(const Signal& s) { 43 | add_signal(s.m_nNumber, s.m_nCallback); 44 | } 45 | 46 | void SignalManager::deleteSignal(const Signal& s) { 47 | remove_signal(s.m_nNumber); 48 | // we need fill remove_signal 49 | m_nNum--; 50 | } 51 | 52 | SignalManager::~SignalManager() { 53 | LOG(Debug) << "class SignalManager destructor\n"; 54 | } -------------------------------------------------------------------------------- /src/tiny_base/signalmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---class SignalManager--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SIGNAL_MANAGER_H 15 | #define SIGNAL_MANAGER_H 16 | 17 | // #include 18 | #include 19 | 20 | // typedef std::function SignalCallback; 21 | typedef void (*SignalCallback)(int); 22 | 23 | class Signal { 24 | private: 25 | int m_nNumber; 26 | std::string m_nName; 27 | std::string m_nMeaning; 28 | SignalCallback m_nCallback; 29 | 30 | public: 31 | Signal(int, const std::string&, const std::string&, SignalCallback); 32 | bool isSame(int signal) const { 33 | return m_nNumber == signal; 34 | } 35 | ~Signal(); 36 | friend class SignalManager; 37 | }; 38 | 39 | class SignalManager { 40 | private: 41 | unsigned char m_nNum; 42 | 43 | public: 44 | SignalManager(); 45 | void addSignal(const Signal&); 46 | void updateSignal(const Signal&); 47 | void deleteSignal(const Signal&); 48 | ~SignalManager(); 49 | }; 50 | 51 | #endif // !SIGNAL_MANAGER_H 52 | -------------------------------------------------------------------------------- /src/tiny_base/sync.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SYNC_H 15 | #define SYNC_H 16 | 17 | #include 18 | #include 19 | 20 | class Sync { 21 | private: 22 | SharedMemory* sem_memory; 23 | // the space for semaphore to synchronize. 24 | 25 | public: 26 | Semaphore* sem; 27 | SharedMemory* memory; 28 | 29 | Sync(unsigned int size) 30 | { 31 | sem_memory = new SharedMemory(sizeof(sem_t)); 32 | sem = new Semaphore(sem_memory, 1); 33 | 34 | memory = new SharedMemory(size); 35 | }; 36 | 37 | ~Sync() 38 | { 39 | delete memory; 40 | delete sem; 41 | delete sem_memory; 42 | }; 43 | }; 44 | 45 | #endif // !SYNC_H 46 | -------------------------------------------------------------------------------- /src/tiny_core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #tiny_core/CMakeLists.txt 2 | 3 | cmake_minimum_required(VERSION 2.8) 4 | 5 | add_definitions("-Wall -std=c++11") 6 | 7 | add_library(tiny_core_model STATIC 8 | accepter.cc 9 | channel.cc 10 | client.cc 11 | clientpool.cc 12 | connection.cc 13 | connector.cc 14 | currentthread.cc 15 | defer.cc 16 | epoller.cc 17 | eventloop.cc 18 | factory.cc 19 | master.cc 20 | netaddress.cc 21 | process.cc 22 | processpool.cc 23 | protocol.cc 24 | server.cc 25 | slave.cc 26 | socket.cc 27 | socketpair.cc 28 | status.cc 29 | thread.cc 30 | threadpool.cc 31 | time.cc 32 | timer.cc 33 | timerqueue.cc 34 | ) 35 | -------------------------------------------------------------------------------- /src/tiny_core/accepter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---class Accepter--- 9 | *This class is used by class Server to accept socket. 10 | **************************************** 11 | *void setConnectionCallback(newConnectionCallback c); 12 | *void listen();//invoke system call listen() 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | void Accepter::m_fHandleRead() 26 | { 27 | NetAddress newConnectionAddress; 28 | int connectfd = m_nListenSocket.accept(newConnectionAddress); 29 | if (connectfd > 0) 30 | { 31 | if (m_nCallback) 32 | m_nCallback(connectfd, newConnectionAddress); 33 | } 34 | else 35 | { 36 | //FIXME: 37 | //handle error event 38 | } 39 | } 40 | 41 | Accepter::Accepter(EventLoop *loop, const NetAddress &server,int listenSocket) 42 | : m_pEventLoop(loop), 43 | m_nListenSocket(listenSocket), 44 | m_nListenChannel(loop, m_nListenSocket.getFd()), 45 | m_nListening(false) 46 | { 47 | m_nListenChannel.setReadCallback( 48 | boost::bind(&Accepter::m_fHandleRead, this)); 49 | //m_nListenSocket.bindAddress(server); 50 | 51 | LOG(Debug) << "class Accepter constructor\n"; 52 | } 53 | 54 | void Accepter::listen() 55 | { 56 | m_nListenChannel.enableRead(); 57 | m_nListenSocket.listen(); 58 | m_nListening = true; 59 | } 60 | 61 | Accepter::~Accepter() 62 | { 63 | LOG(Debug) << "class Accepter destructor\n"; 64 | } -------------------------------------------------------------------------------- /src/tiny_core/accepter.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---class Accepter--- 9 | *This class is used by class Server to accept socket. 10 | **************************************** 11 | * 12 | * 13 | */ 14 | 15 | #ifndef ACCEPTER_H 16 | #define ACCEPTER_H 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | class EventLoop; 24 | 25 | typedef boost::function newConnectionCallback; 26 | 27 | class Accepter 28 | { 29 | private: 30 | EventLoop *m_pEventLoop; 31 | Socket m_nListenSocket; 32 | Channel m_nListenChannel; 33 | newConnectionCallback m_nCallback; 34 | bool m_nListening; 35 | void m_fHandleRead(); 36 | 37 | public: 38 | Accepter(EventLoop *, const NetAddress &,int listenSocket); 39 | void setConnectionCallback(newConnectionCallback c) { m_nCallback = c; } 40 | void listen(); 41 | ~Accepter(); 42 | }; 43 | 44 | #endif // !ACCEPTER_H 45 | -------------------------------------------------------------------------------- /src/tiny_core/callback.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---Configer Class--- 9 | *We need to upgrade this class 10 | *in order to handle config file error 11 | **************************************** 12 | * 13 | */ 14 | 15 | #ifndef CALL_BACK_H 16 | #define CALL_BACK_H 17 | 18 | #include 19 | 20 | #include 21 | 22 | class Buffer; 23 | class Connection; 24 | 25 | typedef boost::function TimerCallback; 26 | typedef boost::function ConnectionCallback; 27 | typedef boost::function 30 | MessageCallback; 31 | typedef boost::function WriteCompleteCallback; 32 | typedef boost::function CloseCallback; 33 | 34 | #endif // !CALL_BACK_H 35 | -------------------------------------------------------------------------------- /src/tiny_core/channel.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---Configer Class--- 9 | *We need to upgrade this class 10 | *in order to handle config file error 11 | **************************************** 12 | * 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | void Channel::m_fUpdate() 20 | { 21 | m_pEventLoop->updateChannel(this); 22 | } 23 | 24 | Channel::Channel(EventLoop *loop, int fd) 25 | { 26 | m_pEventLoop = loop; 27 | m_nFd = fd; 28 | m_nEvent = 0; 29 | m_nREvent = 0; 30 | m_nFlag = ChannelFlag_New; 31 | LOG(Debug) << "class Channel constructor\n"; 32 | } 33 | 34 | void Channel::handleEvent(Time time) 35 | { 36 | // LOG(Debug) << "Epoller revent:" << m_nREvent << std::endl; 37 | // LOG(Debug) << "EOPLLHUP:" << EPOLLHUP 38 | // << "EPOLLIN:" << EPOLLIN 39 | // << ",EPOLLPRI:" << EPOLLPRI 40 | // << ",EPOLLOUT:" << EPOLLOUT 41 | // << ",EPOLLERR:" << EPOLLERR 42 | // << std::endl; 43 | 44 | 45 | if ( (m_nREvent & EPOLLHUP) && !(m_nREvent & EPOLLIN) ) { 46 | if (m_fCloseCallback) 47 | m_fCloseCallback(); 48 | } 49 | 50 | if (m_nREvent & (EPOLLIN | EPOLLRDHUP | EPOLLPRI)) 51 | { 52 | //EPOLLRDHUP is the signal of peer close connection; 53 | if (m_fReadCallback) 54 | m_fReadCallback(time); 55 | } 56 | 57 | if (m_nREvent == EPOLLOUT) 58 | { 59 | if (m_fWriteCallback) 60 | m_fWriteCallback(); 61 | } 62 | 63 | if (m_nREvent & (EPOLLERR)) 64 | { 65 | if (m_fErrorCallback) 66 | m_fErrorCallback(); 67 | } 68 | } 69 | 70 | Channel::~Channel() 71 | { 72 | LOG(Debug) << "class Channel destructor\n"; 73 | } -------------------------------------------------------------------------------- /src/tiny_core/client.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---Client class--- 9 | *This class have same function like Server 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef CLIENT_T 15 | #define CLIENT_T 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | class EventLoop; 24 | class Connector; 25 | class Connection; 26 | class Factory; 27 | 28 | class Client { 29 | private: 30 | bool m_nStarted; 31 | unsigned long long m_nConNum; 32 | 33 | EventLoop* m_pEventLoop; 34 | Factory* m_pFactory; 35 | //pair 36 | typedef std::pair AddressCouple; 37 | typedef std::pair ConnectorCouple; 38 | std::map m_nConnections; 39 | 40 | ConnectionCallback m_nConnectCallback; 41 | MessageCallback m_nMessageCallback; 42 | WriteCompleteCallback m_nWriteCompleteCallback; 43 | CloseCallback m_nCloseCallback; 44 | 45 | void m_fNewConnectionCallback(int, const NetAddress&, 46 | const NetAddress&); 47 | 48 | void m_fHandleClose(Connection*); 49 | 50 | public: 51 | Client(EventLoop*, Factory*); 52 | //setXXXCallback():is a public function 53 | //but it always used by itself to set callback functions 54 | //which is provied by factory. 55 | void setConnectCallback(ConnectionCallback c) 56 | { 57 | m_nConnectCallback = c; 58 | } 59 | void setMessageCallback(MessageCallback c) 60 | { 61 | m_nMessageCallback = c; 62 | } 63 | void setWriteCompleteCallback(WriteCompleteCallback c) 64 | { 65 | m_nWriteCompleteCallback = c; 66 | } 67 | void setCloseCallback(CloseCallback c) 68 | { 69 | m_nCloseCallback = c; 70 | } 71 | void start(); 72 | void connect(const NetAddress& hostAddress, 73 | const NetAddress& peeraddress, 74 | bool retry, 75 | bool keepconnect); 76 | void disconnect(const NetAddress& hostaddress, 77 | const NetAddress& peeraddress); 78 | void disconnectAll(); 79 | void stop(); 80 | ~Client(); 81 | }; 82 | 83 | #endif // !CLIENT_T 84 | -------------------------------------------------------------------------------- /src/tiny_core/connection.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---class Connection--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef CONNECTION_H 15 | #define CONNECTION_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | class Connection; 27 | class Socket; 28 | class EventLoop; 29 | 30 | enum Connection_State { 31 | Connecting, 32 | Connected, 33 | DisConnecting, 34 | DisConnected 35 | }; 36 | 37 | class Connection { 38 | private: 39 | EventLoop* m_pEventLoop; 40 | Connection_State m_nState; 41 | Socket* m_pConnectSocket; //have difference between ListenSocket and connectSocket 42 | Channel* m_pChannel; //handle connect fd 43 | 44 | ConnectionCallback m_nConnectCallback; 45 | MessageCallback m_nMessageCallback; 46 | WriteCompleteCallback m_nWriteCompleteCallback; 47 | CloseCallback m_nCloseCallback; 48 | 49 | Buffer m_nInputBuffer; 50 | Buffer m_nOutputBuffer; 51 | 52 | NetAddress m_nLocalAddress; 53 | NetAddress m_nPeerAddress; 54 | 55 | void m_fHandleRead(Time arrive); 56 | void m_fHandleWrite(); 57 | void m_fHandleClose(); 58 | void m_fHandleError(); 59 | 60 | void m_fShutdownWrite(); 61 | 62 | public: 63 | Connection(EventLoop*, int, const NetAddress&, const NetAddress&); 64 | 65 | void send(const std::string& message); 66 | void send(buffer_t* buffer); 67 | void send(const chain_t* chain); 68 | 69 | void sendfile(int inputFd, off_t* offset, size_t count); 70 | 71 | void setConnectCallback(ConnectionCallback c) 72 | { 73 | m_nConnectCallback = c; 74 | } 75 | void setMessageCallback(MessageCallback c) 76 | { 77 | m_nMessageCallback = c; 78 | } 79 | void setWriteCompleteCallback(WriteCompleteCallback c) 80 | { 81 | m_nWriteCompleteCallback = c; 82 | } 83 | void setCloseCallback(CloseCallback c) 84 | { 85 | m_nCloseCallback = c; 86 | } 87 | 88 | void shutdownWrite() { m_fShutdownWrite(); } 89 | void establishConnection(); 90 | void destoryConnection(); 91 | 92 | NetAddress getLocalAddress() 93 | { 94 | return m_nLocalAddress; 95 | } 96 | NetAddress getPeerAddress() 97 | { 98 | return m_nPeerAddress; 99 | } 100 | 101 | ~Connection(); 102 | }; 103 | 104 | #endif // !CONNECTION_H 105 | -------------------------------------------------------------------------------- /src/tiny_core/connector.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---class Connector--- 9 | *This class has same function like Accepter. 10 | *It is used by client to connect server. 11 | *It will handler more errors. 12 | * reconnect server 13 | * server refuse to connect 14 | * 15 | **************************************** 16 | * 17 | */ 18 | 19 | #ifndef CONNECTOR_T 20 | #define CONNECTOR_T 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | class EventLoop; 28 | 29 | // Distinguish connectionCallback in file callback.h 30 | typedef boost::function newConnectionCallback; 31 | const int MaxRetryDelayMs = 30 * 1000; 32 | const int InitRetryDelayMs = 500; 33 | 34 | class Connector { 35 | private: 36 | enum States { 37 | Disconnected, 38 | Connecting, 39 | Connected 40 | }; 41 | 42 | EventLoop* m_pEventLoop; 43 | // Socket *m_pConnectSocket; 44 | int m_nSockfd; // fd inside of Socket obj 45 | // Because this Socket obj have same fd with 46 | // Socket in Connection,they will close same fd tigger 47 | // close error. 48 | Channel* m_pConnectChannel; 49 | newConnectionCallback m_nNewConnectionCallback; 50 | 51 | NetAddress m_nHostAddress; 52 | NetAddress m_nServerAddress; 53 | States m_nState; 54 | 55 | bool m_nRetry; 56 | bool m_nKeepConnect; 57 | int m_nRetryTime; 58 | bool m_nConnect; // stop will disable that 59 | 60 | TimerId m_nRetryTimer; 61 | 62 | void m_fConnect(); 63 | void m_fRetry(); 64 | 65 | void m_fHandleWrite(); 66 | void m_fHandleError(); 67 | 68 | void m_fRemoveInvaildConnectChannel(); 69 | void m_fRemoveInvaildConnectSocket(); 70 | 71 | void m_fEstablishConnection(); 72 | void m_fRetryConnect(); 73 | 74 | public: 75 | Connector(EventLoop*, const NetAddress&, const NetAddress&, bool retry, bool keepconnect); 76 | int getSocketFd() { return m_nSockfd; } 77 | void setConnectionCallback(newConnectionCallback c) { m_nNewConnectionCallback = c; } 78 | bool isRetry() { return m_nRetry; } 79 | bool isKeepConnect() { return m_nKeepConnect; } 80 | void start(); 81 | void restart(); //invoke when the connection close after 82 | //establish, defferent from retry() 83 | void stop(); 84 | ~Connector(); 85 | }; 86 | 87 | #endif // !CONNECTOR_T -------------------------------------------------------------------------------- /src/tiny_core/currentthread.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | namespace CurrentThread 18 | { 19 | 20 | __thread int t_cachedTid = 0; 21 | __thread char t_tidString[32]; 22 | __thread const char *t_threadName = "unknown"; 23 | void cacheTid() 24 | { 25 | t_cachedTid = gettid(); 26 | snprintf(t_tidString, sizeof t_tidString, "%5d ", 27 | t_cachedTid); 28 | } 29 | } -------------------------------------------------------------------------------- /src/tiny_core/currentthread.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef CURRENT_THREAD_H 15 | #define CURRENT_THREAD_H 16 | 17 | #include 18 | 19 | namespace CurrentThread 20 | { 21 | extern __thread int t_cachedTid; 22 | extern __thread char t_tidString[32]; 23 | extern __thread const char *t_threadName; 24 | 25 | void cacheTid(); 26 | 27 | inline int tid() 28 | { 29 | if (t_cachedTid == 0) 30 | { 31 | cacheTid(); 32 | } 33 | return t_cachedTid; 34 | } 35 | inline const char *tidString() // for logging 36 | { 37 | return t_tidString; 38 | } 39 | inline const char *name() 40 | { 41 | return t_threadName; 42 | } 43 | inline bool isMainThread() 44 | { 45 | return tid() == getpid(); 46 | } 47 | } 48 | 49 | #endif // !CURRENT_THREAD_H 50 | -------------------------------------------------------------------------------- /src/tiny_core/defer.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | void defaultFun() 18 | { 19 | } 20 | 21 | void defauleFunExce(Exception &e) 22 | { 23 | } 24 | 25 | void Defer::m_fRunCallBacks() 26 | { 27 | while (!m_nChains.empty()) 28 | { 29 | Chain tmp = m_nChains.front(); 30 | m_nChains.pop_front(); 31 | callBack c = tmp.first; 32 | errorBack e = tmp.second; 33 | 34 | if (m_nNextChain) 35 | { 36 | try 37 | { 38 | c(); 39 | } 40 | catch (Exception &e) 41 | { 42 | m_nPreException = e; 43 | m_nNextChain = false; 44 | } 45 | catch (...) 46 | { 47 | m_nNextChain = false; 48 | } 49 | } 50 | else 51 | { 52 | try 53 | { 54 | e(m_nPreException); 55 | //If no exception,set m_nNextChain as true; 56 | m_nNextChain = true; 57 | } 58 | catch (Exception &e) 59 | { 60 | m_nPreException = e; 61 | m_nNextChain = false; 62 | } 63 | catch (...) 64 | { 65 | m_nNextChain = false; 66 | } 67 | } 68 | } 69 | } 70 | 71 | Defer::Defer() 72 | : m_nNextChain(true), 73 | m_nPreException("noException"), 74 | m_nIsCalling(false), 75 | m_nCalled(false) 76 | { 77 | LOG(Debug) << "class Defer constructor\n"; 78 | } 79 | 80 | void Defer::addCallBack(callBack c) 81 | { 82 | addCallBacks(c, defauleFunExce); 83 | } 84 | 85 | void Defer::addErrorBack(errorBack e) 86 | { 87 | addCallBacks(defaultFun, e); 88 | } 89 | 90 | void Defer::addCallBacks(callBack c, errorBack e) 91 | { 92 | m_nChains.push_back(Chain(c, e)); 93 | } 94 | 95 | void Defer::callback() 96 | { 97 | if (m_nIsCalling || m_nCalled) 98 | return; 99 | m_nNextChain = true; 100 | m_nIsCalling = true; 101 | m_nCalled = true; 102 | m_fRunCallBacks(); 103 | m_nIsCalling = false; 104 | } 105 | 106 | void Defer::errorback(Exception &exc) 107 | { 108 | if (m_nIsCalling || m_nCalled) 109 | return; 110 | m_nNextChain = false; 111 | m_nPreException = exc; 112 | m_nIsCalling = true; 113 | m_nCalled = true; 114 | m_fRunCallBacks(); 115 | m_nIsCalling = false; 116 | } 117 | 118 | Defer::~Defer() 119 | { 120 | LOG(Debug) << "class Defer constructor\n"; 121 | } -------------------------------------------------------------------------------- /src/tiny_core/defer.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef DEFER_H 15 | #define DEFER_H 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | typedef boost::function callBack; 25 | typedef boost::function errorBack; 26 | 27 | typedef std::pair callBackPair; 28 | typedef std::pair errorBackPair; 29 | 30 | typedef std::pair Chain; 31 | 32 | void defaultFun(); 33 | void defauleFunExce(Exception &e); 34 | 35 | class Defer 36 | { 37 | private: 38 | std::deque m_nChains; 39 | bool m_nNextChain; 40 | Exception m_nPreException; 41 | 42 | bool m_nIsCalling; 43 | bool m_nCalled; 44 | void m_fRunCallBacks(); 45 | 46 | public: 47 | Defer(); 48 | void addCallBack(callBack c); 49 | void addErrorBack(errorBack e); 50 | void addCallBacks(callBack c, errorBack e); 51 | void callback(); 52 | void errorback(Exception &); 53 | ~Defer(); 54 | }; 55 | 56 | #endif // !DEFER_H 57 | -------------------------------------------------------------------------------- /src/tiny_core/epoller.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef EPOLLER_H 15 | #define EPOLLER_H 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | class Channel; 23 | 24 | class EPoller 25 | { 26 | private: 27 | int m_nEFd; 28 | int m_nActiveEventNum; //in poll(),it will be seted by epoll_wait; 29 | //and cleared after invoke m_fFillActiveChannels(), 30 | std::vector m_nActiveEvents; 31 | std::map m_nChannels; 32 | void m_fFillActiveChannels(std::vector &); 33 | void m_fUpdate(int, Channel *); 34 | 35 | public: 36 | EPoller(); 37 | void updateChannel(Channel *); 38 | void removeChannel(Channel *); 39 | Time poll(std::vector &); //epoll_wait to push_back the active channels 40 | ~EPoller(); 41 | }; 42 | 43 | #endif -------------------------------------------------------------------------------- /src/tiny_core/eventloop.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | 26 | extern int status_quit_softly; 27 | extern int status_terminate; 28 | 29 | EventLoop::EventLoop() 30 | { 31 | m_nRunning = true; 32 | m_pPoller = new EPoller(); 33 | m_pTimerQueue = new TimerQueue(this); 34 | LOG(Debug) << "class EventLoop constructor\n"; 35 | } 36 | 37 | void EventLoop::updateChannel(Channel *channel) 38 | { 39 | m_pPoller->updateChannel(channel); 40 | } 41 | 42 | void EventLoop::removeChannel(Channel *channel) 43 | { 44 | m_pPoller->removeChannel(channel); 45 | } 46 | 47 | void EventLoop::loop() 48 | { 49 | while (m_nRunning) 50 | { 51 | m_nActiveChannels.clear(); 52 | Time arriveTime = m_pPoller->poll(m_nActiveChannels); 53 | for (auto t : m_nActiveChannels) 54 | t->handleEvent(arriveTime); 55 | 56 | //stop this loop if get signal SIGINT SIGTERM SIGKILL SIGQUIT 57 | if (status_quit_softly == 1 || status_terminate == 1) 58 | { 59 | std::cout << "process(" << getpid() << ") quit this eventloop\n"; 60 | m_nRunning = false; 61 | } 62 | } 63 | } 64 | 65 | TimerId EventLoop::runAt(Time time, timerReadCallback c) 66 | { 67 | return m_pTimerQueue->addTimer(time, c, false, 0); 68 | } 69 | 70 | TimerId EventLoop::runAfter(double second, timerReadCallback c) 71 | { 72 | Time time = addTime(Time::now(), second); 73 | return m_pTimerQueue->addTimer(time, c, false, 0); 74 | } 75 | 76 | TimerId EventLoop::runEvery(double interval, timerReadCallback c) 77 | { 78 | Time time = addTime(Time::now(), interval); 79 | return m_pTimerQueue->addTimer(time, c, true, interval); 80 | } 81 | 82 | void EventLoop::cancelTimerId(TimerId &timerid) 83 | { 84 | m_pTimerQueue->cancelTimer(timerid); 85 | } 86 | 87 | EventLoop::~EventLoop() 88 | { 89 | delete m_pPoller; 90 | m_pPoller = nullptr; 91 | 92 | delete m_pTimerQueue; 93 | m_pTimerQueue = nullptr; 94 | LOG(Debug) << "class EventLoop destructor\n"; 95 | } 96 | -------------------------------------------------------------------------------- /src/tiny_core/eventloop.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef EVENT_LOOP_H 15 | #define EVENT_LOOP_H 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | class EPoller; 23 | class Channel; 24 | class TimerQueue; 25 | class TimerId; 26 | 27 | class EventLoop 28 | { 29 | private: 30 | bool m_nRunning; 31 | EPoller *m_pPoller; 32 | std::vector m_nActiveChannels; 33 | TimerQueue *m_pTimerQueue; 34 | 35 | public: 36 | EventLoop(); 37 | void updateChannel(Channel *); 38 | void removeChannel(Channel *); 39 | void loop(); 40 | void quit() { m_nRunning = false; } 41 | TimerId runAt(Time, timerReadCallback); 42 | TimerId runAfter(double, timerReadCallback); 43 | TimerId runEvery(double, timerReadCallback); 44 | void cancelTimerId(TimerId &); 45 | 46 | ~EventLoop(); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/tiny_core/master.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | extern int status_terminate; 28 | extern int status_quit_softly; 29 | extern int status_reconfigure; 30 | 31 | Master::Master(ProcessPool* pool, EventLoop* loop, int num, const std::string& name) 32 | : m_pProcessPool(pool) 33 | , m_pEventLoop(loop) 34 | , m_nNumber(num) 35 | , m_nName(name) 36 | , m_nStart(false) 37 | { 38 | LOG(Debug) << "class Master constructor\n"; 39 | } 40 | 41 | void Master::init() 42 | { 43 | Configer& configer = Configer::getConfigerInstance(); 44 | std::vector serverConf = configer.getServerConfig(); 45 | 46 | for (auto t : serverConf) { 47 | NetAddress tmp("172.17.0.2", t.listen); 48 | Socket* socket = new Socket(createNoBlockSocket()); 49 | socket->bindAddress(tmp); 50 | 51 | NetSocketPair newPair(tmp, socket); 52 | m_nListenSockets.push_back(newPair); 53 | // FIXME:how to handle the problem of same listen-address. 54 | 55 | LOG(Info) << "bind address(" << tmp.getIpPort() << ")\n"; 56 | } 57 | } 58 | 59 | void Master::getListenSockets(std::vector& result) 60 | { 61 | result.clear(); 62 | result.assign(m_nListenSockets.begin(), m_nListenSockets.end()); 63 | } 64 | 65 | void Master::work() 66 | { 67 | LOG(Debug) << "[master]:start working\n"; 68 | m_nStart = true; 69 | 70 | while (m_nStart) { 71 | m_pEventLoop->loop(); 72 | if (status_terminate || status_quit_softly) { 73 | LOG(Debug) << "[master]:(term/stop)I will kill all chilern\n"; 74 | m_pProcessPool->killAll(); 75 | m_nStart = false; 76 | } 77 | if (status_restart || status_reconfigure) { 78 | LOG(Debug) << "[master]:(restart/reload)quit and create new processpool\n"; 79 | m_pProcessPool->killAll(); 80 | m_nStart = false; 81 | } 82 | } 83 | } 84 | 85 | Master::~Master() 86 | { 87 | for (auto t : m_nListenSockets) { 88 | delete t.second; 89 | } 90 | LOG(Debug) << "class Master destructor\n"; 91 | } 92 | -------------------------------------------------------------------------------- /src/tiny_core/master.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef MASTER_H 15 | #define MASTER_H 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | class ProcessPool; 22 | class EventLoop; 23 | class NetAddress; 24 | class Socket; 25 | 26 | class Master { 27 | protected: 28 | ProcessPool* m_pProcessPool; 29 | EventLoop* m_pEventLoop; 30 | int m_nNumber; 31 | std::string m_nName; 32 | 33 | typedef std::pair NetSocketPair; 34 | std::vector m_nListenSockets; 35 | 36 | bool m_nStart; 37 | 38 | public: 39 | Master(ProcessPool*, EventLoop*, int, const std::string&); 40 | void init(); 41 | void getListenSockets(std::vector& result); 42 | void work(); 43 | ~Master(); 44 | }; 45 | 46 | #endif // !MASTER_H 47 | -------------------------------------------------------------------------------- /src/tiny_core/netaddress.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef NET_ADDRESS_H 15 | #define NET_ADDRESS_H 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | class NetAddress 22 | { 23 | private: 24 | struct sockaddr_in m_nAddress; 25 | 26 | public: 27 | NetAddress(); 28 | NetAddress(const NetAddress &); 29 | NetAddress(int port); 30 | NetAddress(const std::string &ip, int port); 31 | NetAddress(const std::string &ipport); 32 | NetAddress(struct sockaddr_in &addr); 33 | NetAddress &operator=(const NetAddress &); 34 | 35 | std::string getIp() const; 36 | int getPort() const; 37 | std::string getIpPort() const; 38 | 39 | const struct sockaddr_in getAddr() const { return m_nAddress; } 40 | void setAddr(struct sockaddr_in a) { m_nAddress = a; } 41 | 42 | friend bool operator==(const NetAddress &a, const NetAddress &b) 43 | { 44 | return !memcmp(&a.m_nAddress, &b.m_nAddress, sizeof(struct sockaddr_in)); 45 | } 46 | friend bool operator<(const NetAddress &a, const NetAddress &b) 47 | { 48 | return memcmp(&a.m_nAddress, &b.m_nAddress, sizeof(struct sockaddr_in)); 49 | } 50 | ~NetAddress(); 51 | }; 52 | 53 | #endif // !NET_ADDRESS_H 54 | -------------------------------------------------------------------------------- /src/tiny_core/server.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | void Server::m_fHandleRead(int connectfd, const NetAddress& address) 26 | { 27 | // NetAddress local(getLocalAddr()); 28 | Connection* newCon = new Connection(m_pEventLoop, 29 | connectfd, 30 | m_nListenAddress, 31 | address); 32 | m_nConNum++; 33 | // std::cout << m_nConNum << std::endl; 34 | newCon->setConnectCallback(m_nConnectCallback); 35 | newCon->setMessageCallback(m_nMessageCallback); 36 | newCon->setWriteCompleteCallback(m_nWriteCompleteCallback); 37 | newCon->setCloseCallback(boost::bind(&Server::m_fHandleClose, this, _1)); 38 | m_nConnections.insert(newCon); 39 | newCon->establishConnection(); 40 | } 41 | 42 | void Server::m_fHandleClose(Connection* con) 43 | { 44 | if (m_nCloseCallback) 45 | m_nCloseCallback(con); 46 | // std::cout << "lib code:remove connection\n"; 47 | con->destoryConnection(); 48 | auto p = m_nConnections.find(con); 49 | delete (*p); 50 | m_nConnections.erase(p); 51 | } 52 | 53 | Server::Server(EventLoop* loop, const NetAddress& address, 54 | int listenSocket, Factory* fact) 55 | : m_nStarted(false) 56 | , m_nConNum(0) 57 | , m_nListenAddress(address) 58 | , m_pEventLoop(loop) 59 | , m_pFactory(fact) 60 | , m_nAccepter(loop, address, listenSocket) 61 | { 62 | m_nAccepter.setConnectionCallback( 63 | boost::bind(&Server::m_fHandleRead, this, _1, _2)); 64 | if (m_pFactory != nullptr) { 65 | setConnectCallback(m_pFactory->connectCallback()); 66 | setMessageCallback(m_pFactory->getMessageCallback()); 67 | setWriteCompleteCallback(m_pFactory->writeCompleteCallback()); 68 | setCloseCallback(m_pFactory->closeConnectionCallback()); 69 | } 70 | 71 | LOG(Debug) << "class Server constructor\n"; 72 | } 73 | 74 | void Server::start() 75 | { 76 | if (!m_nStarted) { 77 | m_nAccepter.listen(); 78 | m_nStarted = true; 79 | } 80 | } 81 | 82 | Server::~Server() 83 | { 84 | LOG(Info) << "rest connection number:" << m_nConnections.size() << std::endl; 85 | 86 | //have connection not done 87 | for (auto t : m_nConnections) { 88 | t->shutdownWrite(); 89 | t->destoryConnection(); 90 | delete t; 91 | //Think carefully. 92 | } 93 | LOG(Debug) << "class Server destructor\n"; 94 | } 95 | -------------------------------------------------------------------------------- /src/tiny_core/server.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SERVER_H 15 | #define SERVER_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | class EventLoop; 28 | class Connection; 29 | class Factory; 30 | 31 | class Server { 32 | private: 33 | bool m_nStarted; 34 | unsigned long long m_nConNum; 35 | NetAddress m_nListenAddress; 36 | EventLoop* m_pEventLoop; 37 | Factory* m_pFactory; 38 | Accepter m_nAccepter; 39 | std::set m_nConnections; 40 | 41 | ConnectionCallback m_nConnectCallback; 42 | MessageCallback m_nMessageCallback; 43 | WriteCompleteCallback m_nWriteCompleteCallback; 44 | CloseCallback m_nCloseCallback; 45 | 46 | void m_fHandleRead(int, const NetAddress&); 47 | void m_fHandleClose(Connection*); 48 | 49 | public: 50 | Server(EventLoop*, const NetAddress&, int listenSocket, Factory*); 51 | void setConnectCallback(ConnectionCallback c) 52 | { 53 | m_nConnectCallback = c; 54 | } 55 | void setMessageCallback(MessageCallback c) 56 | { 57 | m_nMessageCallback = c; 58 | } 59 | void setWriteCompleteCallback(WriteCompleteCallback c) 60 | { 61 | m_nWriteCompleteCallback = c; 62 | } 63 | void setCloseCallback(CloseCallback c) 64 | { 65 | m_nCloseCallback = c; 66 | } 67 | void start(); 68 | ~Server(); 69 | }; 70 | 71 | #endif // !SERVER_H 72 | -------------------------------------------------------------------------------- /src/tiny_core/slave.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | Slave::Slave(EventLoop* loop, int num, const std::string& name) 26 | : m_pEventLoop(loop) 27 | , m_nNumber(num) 28 | , m_nName(name) 29 | // , m_nListenAddress(NetAddress("172.17.0.2:9090")) 30 | { 31 | LOG(Debug) << "class Slave constructor\n"; 32 | } 33 | 34 | void Slave::createListenServer(const NetSocketPair& pair) 35 | { 36 | Protocol* protocol = new WebProtocol(); 37 | Factory* factory = new Factory(m_pEventLoop, protocol); 38 | Server* server = new Server(m_pEventLoop, pair.first, 39 | pair.second->getFd(), factory); 40 | VritualMachine newMachine(protocol, factory, 41 | pair.second->getFd(), server); 42 | 43 | m_nMachines.push_back(newMachine); 44 | } 45 | 46 | #include 47 | extern int status_quit_softly; //QUIT 48 | extern int status_terminate; //TERM,INT 49 | extern int status_exiting; 50 | extern int status_reconfigure; //HUP,reboot 51 | extern int status_child_quit; //CHLD 52 | 53 | void Slave::work() 54 | { 55 | for (auto t : m_nMachines) { 56 | t.m_pServer->start(); 57 | } 58 | m_nStart = true; 59 | 60 | while (m_nStart) { 61 | m_pEventLoop->loop(); 62 | // reconfig 63 | 64 | if (status_terminate || status_quit_softly || status_restart || status_reconfigure) 65 | m_nStart = false; 66 | } 67 | } 68 | 69 | Slave::~Slave() 70 | { 71 | for (auto t : m_nMachines) { 72 | delete t.m_pProtocol; 73 | delete t.m_pFactory; 74 | delete t.m_pServer; 75 | } 76 | LOG(Debug) << "class Slave destructor\n"; 77 | } 78 | -------------------------------------------------------------------------------- /src/tiny_core/slave.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SLAVE_H 15 | #define SLAVE_H 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | class EventLoop; 24 | class Protocol; 25 | class Factory; 26 | class Server; 27 | 28 | class VritualMachine { 29 | public: 30 | Protocol* m_pProtocol; 31 | Factory* m_pFactory; 32 | int m_nListenSocketFd; 33 | Server* m_pServer; 34 | 35 | VritualMachine(Protocol* protocol, 36 | Factory* factory, 37 | int listenFd, 38 | Server* server) 39 | : m_pProtocol(protocol) 40 | , m_pFactory(factory) 41 | , m_nListenSocketFd(listenFd) 42 | , m_pServer(server) 43 | { 44 | LOG(Debug) << "class VritualMachine constructor\n"; 45 | } 46 | }; 47 | 48 | class Slave { 49 | protected: 50 | EventLoop* m_pEventLoop; 51 | int m_nNumber; 52 | std::string m_nName; 53 | 54 | // NetAddress m_nListenAddress; // TODO:delete 55 | 56 | std::vector m_nMachines; 57 | 58 | bool m_nStart; 59 | 60 | typedef std::pair NetSocketPair; 61 | public: 62 | Slave(EventLoop*, int, const std::string&); 63 | void createListenServer(const NetSocketPair& pair); 64 | void work(); 65 | ~Slave(); 66 | }; 67 | 68 | #endif //!SLAVE_H 69 | -------------------------------------------------------------------------------- /src/tiny_core/socket.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | Socket::Socket(int fd) 23 | { 24 | m_nFd = fd; 25 | m_nClosed = false; 26 | setSocketReuseAddress(fd); //SO_REUSEADDR 27 | LOG(Debug) << "class Socket constructor\n"; 28 | } 29 | 30 | void Socket::bindAddress(const NetAddress &address) 31 | { 32 | struct sockaddr_in s = address.getAddr(); 33 | Bind(m_nFd, &s); 34 | //setSocketReuseAddress(m_nFd); 35 | } 36 | void Socket::listen() 37 | { 38 | Listen(m_nFd, 100); 39 | } 40 | 41 | int Socket::accept(NetAddress &per) 42 | { 43 | struct sockaddr_in addr; 44 | bzero(&addr, sizeof(addr)); 45 | int connectfd = Accept(m_nFd, &addr); 46 | per.setAddr(addr); 47 | return connectfd; 48 | } 49 | 50 | int Socket::connect(const NetAddress &per) 51 | { 52 | struct sockaddr_in addr; 53 | bzero(&addr, sizeof(addr)); 54 | addr = per.getAddr(); 55 | return Connect(m_nFd, &addr); 56 | } 57 | 58 | void Socket::shutdownWrite() 59 | { 60 | ShutdownWrite(m_nFd); 61 | } 62 | 63 | void Socket::close() 64 | { 65 | if (m_nClosed == false) 66 | { 67 | Close(m_nFd); 68 | m_nClosed = true; 69 | } 70 | } 71 | 72 | void Socket::setNoDelay() 73 | { 74 | //disable tcp Nagle algorithm. 75 | disableTcpDelay(m_nFd); 76 | } 77 | 78 | void Socket::setDelay() 79 | { 80 | //I think this function has bug, 81 | //FIXME: 82 | enableTcpDelay(m_nFd); 83 | } 84 | 85 | void Socket::setKeepAlive() 86 | { 87 | enableTcpKeepAlive(m_nFd); 88 | } 89 | 90 | void Socket::setNoKeepAlive() 91 | { 92 | //I think this function has bug, 93 | //FIXME: 94 | disableTcpKeepAlive(m_nFd); 95 | } 96 | 97 | Socket::~Socket() 98 | { 99 | if (m_nClosed == false) 100 | { 101 | Close(m_nFd); 102 | m_nClosed = true; 103 | } 104 | LOG(Debug) << "class Socket destructor\n"; 105 | } -------------------------------------------------------------------------------- /src/tiny_core/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SOCKET_H 15 | #define SOCKET_H 16 | 17 | class NetAddress; 18 | 19 | class Socket 20 | { 21 | private: 22 | int m_nFd; 23 | bool m_nClosed; 24 | 25 | public: 26 | Socket(int); 27 | int getFd() { return m_nFd; } 28 | void bindAddress(const NetAddress &); 29 | void listen(); 30 | int accept(NetAddress &per); 31 | int connect(const NetAddress &per); 32 | void shutdownWrite(); 33 | void close(); 34 | void setNoDelay(); 35 | void setDelay(); 36 | void setKeepAlive(); 37 | void setNoKeepAlive(); 38 | ~Socket(); 39 | }; 40 | 41 | #endif -------------------------------------------------------------------------------- /src/tiny_core/socketpair.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef SOCKET_PAIR_H 15 | #define SOCKET_PAIR_H 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | class EventLoop; 25 | 26 | class SocketPair { 27 | private: 28 | //parent using 0,child using 1 29 | EventLoop* m_pEventLoop; 30 | int m_nFds[2]; 31 | Connection* m_pConnection; 32 | 33 | bool m_nIsParent; 34 | 35 | public: 36 | SocketPair(EventLoop* loop, int fds[2]); 37 | void setParentSocket(int port); 38 | void setChildSocket(int port); 39 | void writeToChild(const std::string& data); 40 | void writeToParent(const std::string& data); 41 | 42 | void setConnectCallback(const ConnectionCallback& c); 43 | void setMessageCallback(const MessageCallback& c); 44 | void setWriteCompleteCallback(const WriteCompleteCallback& c); 45 | void setCloseCallback(const CloseCallback& c); 46 | 47 | void clearSocket(); 48 | ~SocketPair(); 49 | }; 50 | 51 | #endif //!SOCKET_PAIR_H 52 | -------------------------------------------------------------------------------- /src/tiny_core/status.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | int status_quit_softly = 0; //QUIT 17 | int status_terminate = 0; //TERM,INT 18 | int status_exiting = 0; 19 | int status_restart = 0; 20 | int status_reconfigure = 0; //HUP,reboot 21 | int status_child_quit = 0; //CHLD 22 | -------------------------------------------------------------------------------- /src/tiny_core/status.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef TINYWEB_STATUS_H 15 | #define TINYWEB_STATUS_H 16 | 17 | extern int status_quit_softly; //QUIT 18 | extern int status_terminate; //TERM,INT 19 | extern int status_exiting; 20 | extern int status_restart; 21 | extern int status_reconfigure; //HUP,reboot 22 | extern int status_child_quit; //CHLD 23 | 24 | #endif //!TINYWEB_STATUS_H 25 | -------------------------------------------------------------------------------- /src/tiny_core/thread.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | AtomicInt32 Thread::m_nThreadsNum; 20 | 21 | void *Thread::m_fStartThread(void *arg) 22 | { 23 | Thread *thread = (Thread *)arg; 24 | thread->runInThread(); 25 | return nullptr; 26 | } 27 | 28 | void Thread::runInThread() 29 | { 30 | //invoke the thread_function 31 | m_nTid = CurrentThread::tid(); 32 | CurrentThread::t_threadName = m_nName.c_str(); 33 | m_fThreadFun(); 34 | CurrentThread::t_threadName = "finished"; 35 | //don't finised 36 | //must handle the exception 37 | } 38 | 39 | Thread::Thread(const threadFun &fun, 40 | const std::string &name) 41 | { 42 | m_nName = name; 43 | m_nThreadId = 0; 44 | m_nTid = 0; 45 | m_fThreadFun = fun; 46 | m_nStarted = false; 47 | m_nJoined = false; 48 | m_nThreadsNum.increment(); 49 | } 50 | 51 | void Thread::start() 52 | { 53 | m_nStarted = true; 54 | int res = pthread_create(&m_nThreadId, NULL, 55 | m_fStartThread, this); 56 | if (res != 0) 57 | handle_error_s("pthread_create() error"); 58 | } 59 | 60 | int Thread::join() 61 | { 62 | m_nJoined = true; 63 | return pthread_join(m_nThreadId, NULL); 64 | } 65 | 66 | bool Thread::started() 67 | { 68 | return m_nStarted; 69 | } 70 | 71 | pid_t Thread::getTid() 72 | { 73 | return m_nTid; 74 | } 75 | 76 | const std::string &Thread::getName() 77 | { 78 | return m_nName; 79 | } 80 | 81 | int Thread::numCreated() 82 | { 83 | return m_nThreadsNum.get(); 84 | } 85 | 86 | Thread::~Thread() 87 | { 88 | if (!m_nJoined) 89 | pthread_detach(m_nThreadId); 90 | } -------------------------------------------------------------------------------- /src/tiny_core/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.generalsandman.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef THREAD_T 15 | #define THREAD_T 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | typedef boost::function threadFun; 25 | class Thread : boost::noncopyable 26 | { 27 | private: 28 | std::string m_nName; 29 | pthread_t m_nThreadId; 30 | pid_t m_nTid; 31 | 32 | threadFun m_fThreadFun; 33 | bool m_nStarted; 34 | bool m_nJoined; 35 | 36 | //m_nFStartThread must be static function 37 | // why:http://www.xuebuyuan.com/779187.html 38 | static void *m_fStartThread(void *); // 39 | void runInThread(); 40 | static AtomicInt32 m_nThreadsNum; 41 | 42 | public: 43 | explicit Thread(const threadFun &, const std::string &name=""); 44 | //constructor don't create thread 45 | //start() create thread 46 | void start(); 47 | int join(); 48 | bool started(); 49 | pid_t getTid(); 50 | const std::string &getName(); 51 | static int numCreated(); 52 | 53 | ~Thread(); 54 | }; 55 | 56 | #endif // !THREAD_T 57 | -------------------------------------------------------------------------------- /src/tiny_core/threadpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef THREAD_POOL_H 15 | #define THREAD_POOL_H 16 | 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | typedef boost::function Task; 29 | 30 | class ThreadPool : boost::noncopyable 31 | { 32 | private: 33 | std::string m_nName; 34 | MutexLock m_nMutexLock; 35 | Condition m_nCondition_notEmpty; 36 | Condition m_nCondition_notFull; 37 | unsigned int m_nMaxQueueSize; 38 | std::deque m_nQueue; 39 | boost::ptr_vector m_nThreads; 40 | bool m_nRunning; 41 | 42 | void m_fRunInThread(); 43 | Task m_fTake(); 44 | bool m_fIsFull(); 45 | 46 | public: 47 | //constructer don't create thread 48 | //start(n) create n theads 49 | explicit ThreadPool(const std::string &a = "", 50 | int maxqueuesize = 100); 51 | void start(int); 52 | void stop(); 53 | bool run(const Task &); 54 | ~ThreadPool(); 55 | }; 56 | 57 | #endif // !THREAD_POOL_H 58 | -------------------------------------------------------------------------------- /src/tiny_core/time.cc: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #define __STDC_FORMAT_MACROS 20 | #include 21 | #undef __STDC_FORMAT_MACROS 22 | 23 | #include 24 | #include 25 | 26 | BOOST_STATIC_ASSERT(sizeof(Time) == sizeof(int64_t)); 27 | 28 | Time::Time(int64_t microseconds) 29 | : microSecondsSinceEpoch_(microseconds) 30 | { 31 | } 32 | 33 | std::string Time::toString() const 34 | { 35 | char buf[32] = {0}; 36 | int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond; 37 | int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond; 38 | snprintf(buf, sizeof(buf) - 1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds); 39 | return buf; 40 | } 41 | 42 | std::string Time::toFormattedString() const 43 | { 44 | char buf[32] = {0}; 45 | time_t seconds = static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); 46 | int microseconds = static_cast(microSecondsSinceEpoch_ % kMicroSecondsPerSecond); 47 | struct tm tm_time; 48 | gmtime_r(&seconds, &tm_time); 49 | 50 | snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d", 51 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 52 | tm_time.tm_hour + 8, tm_time.tm_min, tm_time.tm_sec, 53 | microseconds); 54 | //tm_time.tm_hour + 8 :is the Beijing TimeZone 55 | return buf; 56 | } 57 | 58 | Time Time::now() 59 | { 60 | struct timeval tv; 61 | gettimeofday(&tv, NULL); 62 | int64_t seconds = tv.tv_sec; 63 | return Time(seconds * kMicroSecondsPerSecond + tv.tv_usec); 64 | } 65 | 66 | Time Time::invalid() 67 | { 68 | return Time(); 69 | } 70 | -------------------------------------------------------------------------------- /src/tiny_core/time.h: -------------------------------------------------------------------------------- 1 | /* 2 | *Author:GeneralSandman 3 | *Code:https://github.com/GeneralSandman/TinyWeb 4 | *E-mail:generalsandman@163.com 5 | *Web:www.dissigil.cn 6 | */ 7 | 8 | /*---XXX--- 9 | * 10 | **************************************** 11 | * 12 | */ 13 | 14 | #ifndef TIME_H 15 | #define TIME_H 16 | 17 | #include 18 | #include 19 | 20 | class Time : public boost::less_than_comparable