├── pink ├── test │ ├── gtest │ │ ├── .gitignore │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── src │ │ │ ├── gtest_main.cc │ │ │ ├── gtest-all.cc │ │ │ ├── gtest-typed-test.cc │ │ │ └── gtest-test-part.cc │ │ ├── include │ │ │ └── gtest │ │ │ │ ├── internal │ │ │ │ ├── custom │ │ │ │ │ ├── gtest.h │ │ │ │ │ ├── gtest-printers.h │ │ │ │ │ └── gtest-port.h │ │ │ │ └── gtest-port-arch.h │ │ │ │ └── gtest_prod.h │ │ └── CHANGES │ ├── gmock │ │ ├── include │ │ │ └── gmock │ │ │ │ ├── internal │ │ │ │ ├── custom │ │ │ │ │ ├── gmock-generated-actions.h │ │ │ │ │ ├── gmock-generated-actions.h.pump │ │ │ │ │ ├── gmock-matchers.h │ │ │ │ │ └── gmock-port.h │ │ │ │ ├── gmock-port.h │ │ │ │ └── gmock-generated-internal-utils.h.pump │ │ │ │ ├── gmock-more-matchers.h │ │ │ │ ├── gmock.h │ │ │ │ ├── gmock-cardinalities.h │ │ │ │ └── gmock-generated-nice-strict.h.pump │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── src │ │ │ ├── gmock-all.cc │ │ │ ├── gmock_main.cc │ │ │ └── gmock-cardinalities.cc │ │ └── CHANGES │ └── Makefile ├── examples │ ├── performance │ │ ├── message.proto │ │ ├── README.md │ │ ├── Makefile │ │ ├── client.cc │ │ └── server.cc │ ├── myproto.proto │ ├── README.md │ ├── myproto_cli.cc │ ├── Makefile │ ├── mydispatch_srv.cc │ ├── myholy_srv.cc │ ├── simple_http_server.cc │ ├── bg_thread.cc │ ├── myredis_srv.cc │ ├── http_server.cc │ ├── myholy_srv_chandle.cc │ ├── https_server.cc │ └── redis_cli_test.cc ├── src │ ├── build_version.cc.in │ ├── pink_util.h │ ├── period_thread.cc │ ├── pink_util.cc │ ├── pink_item.h │ ├── pink_epoll.h │ ├── pink_thread_name.h │ ├── test │ │ └── pink_thread_test.cc │ ├── pink_thread.cc │ ├── pink_conn.cc │ ├── server_socket.h │ ├── server_socket.cc │ ├── holy_thread.h │ ├── pink_epoll.cc │ ├── dispatch_thread.h │ ├── pb_cli.cc │ ├── worker_thread.h │ ├── bg_thread.cc │ └── pb_conn.cc ├── build.sh ├── include │ ├── period_thread.h │ ├── build_version.h │ ├── redis_cli.h │ ├── pink_thread.h │ ├── redis_conn.h │ ├── pink_cli.h │ ├── bg_thread.h │ ├── pink_define.h │ ├── pb_conn.h │ ├── pink_conn.h │ ├── pink_pubsub.h │ ├── simple_http_conn.h │ └── http_conn.h └── Makefile ├── .travis.yml ├── .gitignore ├── LICENSE └── README.md /pink/test/gtest/.gitignore: -------------------------------------------------------------------------------- 1 | # python 2 | *.pyc 3 | -------------------------------------------------------------------------------- /pink/examples/performance/message.proto: -------------------------------------------------------------------------------- 1 | message Ping { 2 | required string ping = 1; 3 | } 4 | 5 | message Pong { 6 | required string pong = 1; 7 | } 8 | -------------------------------------------------------------------------------- /pink/examples/myproto.proto: -------------------------------------------------------------------------------- 1 | package myproto; 2 | 3 | message Ping { 4 | required string address = 2; 5 | required int32 port = 3; 6 | } 7 | 8 | message PingRes { 9 | required int32 res = 1; 10 | required string mess = 2; 11 | } 12 | -------------------------------------------------------------------------------- /pink/src/build_version.cc.in: -------------------------------------------------------------------------------- 1 | #include "pink/include/build_version.h" 2 | const char* pink_build_git_sha = "pink_build_git_sha:@@GIT_SHA@@"; 3 | const char* pink_build_git_date = "pink_build_git_date:@@GIT_DATE_TIME@@"; 4 | const char* pink_build_compile_date = __DATE__; 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | language: cpp 4 | 5 | os: 6 | - linux 7 | 8 | addons: 9 | apt: 10 | packages: ['zlib1g-dev', 'libbz2-dev', 'libsnappy-dev', 'curl', 'libprotobuf-dev', 'protobuf-compiler'] 11 | 12 | compiler: 13 | - gcc 14 | 15 | language: cpp 16 | 17 | script: 18 | - cd pink && ./build.sh 19 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/internal/custom/gmock-generated-actions.h: -------------------------------------------------------------------------------- 1 | // This file was GENERATED by command: 2 | // pump.py gmock-generated-actions.h.pump 3 | // DO NOT EDIT BY HAND!!! 4 | 5 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 6 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 7 | 8 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 9 | -------------------------------------------------------------------------------- /pink/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PINK_PATH=$PWD 4 | 5 | # We depend on slash 6 | SLASH_PATH=$1 7 | if test -z $SLASH_PATH; then 8 | SLASH_PATH=$PINK_PATH/third/slash 9 | fi 10 | 11 | if [[ ! -d $SLASH_PATH ]]; then 12 | mkdir -p $SLASH_PATH 13 | git clone https://github.com/Qihoo360/slash.git $SLASH_PATH 14 | fi 15 | cd $SLASH_PATH/slash && make 16 | 17 | # Compile pink 18 | cd $PINK_PATH 19 | make SLASH_PATH=$SLASH_PATH 20 | cd examples && make SLASH_PATH=$SLASH_PATH 21 | -------------------------------------------------------------------------------- /pink/examples/performance/README.md: -------------------------------------------------------------------------------- 1 | client and server code used to get pink performance benchmark 2 | 3 | ### usage 4 | 5 | after compiler you will get two executable program server and client 6 | 7 | start server 8 | ./server 127.0.0.1(you ip) port(listen port) 9 | 10 | ./client 127.0.0.1(server ip) port(sever port) 11 | 12 | since there should be many clients to get the pink's performance limitation, 13 | so in our case, we will always have 10~20 client to pressure measure server 14 | -------------------------------------------------------------------------------- /pink/examples/README.md: -------------------------------------------------------------------------------- 1 | myproto.proto the proto buffer file used to test pb protocol 2 | 3 | myholy_srv.cc server side of myproto.proto with holy thread 4 | 5 | mydispatch_srv.cc server side of myproto.proto with dispatch thread and worker thread 6 | 7 | myproto_cli.cc client support myproto.proto 8 | 9 | myredis_srv.cc A simple server support redis protocol, it can be used to test the performance of pink with redis protocol 10 | 11 | performance/ client and server code used to get performance benchmark 12 | -------------------------------------------------------------------------------- /pink/src/pink_util.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_PINK_UTIL_H_ 7 | #define PINK_SRC_PINK_UTIL_H_ 8 | 9 | namespace pink { 10 | 11 | int Setnonblocking(int sockfd); 12 | 13 | } // namespace pink 14 | 15 | #endif // PINK_SRC_PINK_UTIL_H_ 16 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/internal/custom/gmock-generated-actions.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $$ This is a Pump source file (http://go/pump). Please use Pump to convert 3 | $$ it to callback-actions.h. 4 | $$ 5 | $var max_callback_arity = 5 6 | $$}} This meta comment fixes auto-indentation in editors. 7 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 8 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 9 | 10 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 11 | -------------------------------------------------------------------------------- /pink/src/period_thread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "pink/include/period_thread.h" 7 | 8 | #include 9 | 10 | namespace pink { 11 | 12 | PeriodThread::PeriodThread(struct timeval period) : 13 | period_(period) { 14 | } 15 | 16 | void *PeriodThread::ThreadMain() { 17 | PeriodMain(); 18 | select(0, NULL, NULL, NULL, &period_); 19 | return NULL; 20 | } 21 | 22 | } // namespace pink 23 | -------------------------------------------------------------------------------- /pink/examples/performance/Makefile: -------------------------------------------------------------------------------- 1 | ifndef SLASH_PATH 2 | SLASH_PATH=../../third/slash 3 | endif 4 | 5 | ifndef PINK_PATH 6 | PINK_PATH=../../../ 7 | endif 8 | 9 | CXXFLAGS= -O2 -I$(PINK_PATH) -I$(SLASH_PATH) -std=c++11 10 | LDFLAGS= -L$(SLASH_PATH)/slash/lib -L$(PINK_PATH)/pink/lib -lprotobuf -lpink -lslash -lpthread 11 | 12 | .PHONY: all 13 | 14 | all: server client 15 | 16 | server: message.pb.o server.o 17 | $(CXX) -o $@ $^ $(LDFLAGS) 18 | 19 | client: message.pb.o client.o 20 | $(CXX) -o $@ $^ $(LDFLAGS) 21 | 22 | %.o: %.cc 23 | $(CXX) -c $< $(CXXFLAGS) 24 | 25 | message.pb.cc: 26 | protoc --proto_path=./ --cpp_out=./ ./message.proto 27 | 28 | clean: 29 | rm -f server client *.o message.pb.* 30 | -------------------------------------------------------------------------------- /pink/include/period_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PERIOD_THREAD_H_ 7 | #define PINK_INCLUDE_PERIOD_THREAD_H_ 8 | 9 | #include 10 | 11 | #include "pink/include/pink_thread.h" 12 | 13 | namespace pink { 14 | 15 | class PeriodThread : public Thread { 16 | public: 17 | explicit PeriodThread(struct timeval period = (struct timeval){1, 0}); 18 | virtual void *ThreadMain(); 19 | virtual void PeriodMain() = 0; 20 | 21 | private: 22 | struct timeval period_; 23 | }; 24 | 25 | } // namespace pink 26 | #endif // PINK_INCLUDE_PERIOD_THREAD_H_ 27 | -------------------------------------------------------------------------------- /pink/src/pink_util.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | #include "pink/src/pink_util.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "pink/include/pink_define.h" 12 | 13 | namespace pink { 14 | 15 | int Setnonblocking(int sockfd) { 16 | int flags; 17 | if ((flags = fcntl(sockfd, F_GETFL, 0)) < 0) { 18 | close(sockfd); 19 | return -1; 20 | } 21 | flags |= O_NONBLOCK; 22 | if (fcntl(sockfd, F_SETFL, flags) < 0) { 23 | close(sockfd); 24 | return -1; 25 | } 26 | return flags; 27 | } 28 | 29 | } // namespace pink 30 | -------------------------------------------------------------------------------- /pink/src/pink_item.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_PINK_ITEM_H_ 7 | #define PINK_SRC_PINK_ITEM_H_ 8 | 9 | #include 10 | 11 | #include "pink/include/pink_define.h" 12 | 13 | namespace pink { 14 | 15 | class PinkItem { 16 | public: 17 | PinkItem() {} 18 | PinkItem(const int fd, const std::string &ip_port) 19 | : fd_(fd), 20 | ip_port_(ip_port) { 21 | } 22 | 23 | int fd() const { 24 | return fd_; 25 | } 26 | std::string ip_port() const { 27 | return ip_port_; 28 | } 29 | 30 | private: 31 | int fd_; 32 | std::string ip_port_; 33 | }; 34 | 35 | } // namespace pink 36 | #endif // PINK_SRC_PINK_ITEM_H_ 37 | -------------------------------------------------------------------------------- /pink/include/build_version.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | // 6 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 7 | // This source code is licensed under the BSD-style license found in the 8 | // LICENSE file in the root directory of this source tree. An additional grant 9 | // of patent rights can be found in the PATENTS file in the same directory. 10 | // 11 | #ifndef PINK_INCLUDE_BUILD_VERSION_H_ 12 | #define PINK_INCLUDE_BUILD_VERSION_H_ 13 | 14 | // this variable tells us about the git revision 15 | extern const char* pink_build_git_sha; 16 | 17 | // Date on which the code was compiled: 18 | extern const char* pink_build_compile_date; 19 | 20 | #endif // PINK_INCLUDE_BUILD_VERSION_H_ 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | pink/output/ 30 | 31 | # Examples 32 | pink/examples/*.pb.h 33 | pink/examples/*.pb.cc 34 | pink/examples/output/ 35 | pink/examples/cli/cli 36 | pink/examples/performance/client 37 | pink/examples/performance/message.pb.cc 38 | pink/examples/performance/message.pb.h 39 | pink/examples/performance/server 40 | pink/examples/myproto.pb.cc 41 | pink/examples/myproto.pb.h 42 | *bg_thread 43 | *http_server 44 | *mydispatch_srv 45 | *myholy_srv 46 | *myholy_srv_chandle 47 | *myproto_cli 48 | *redis_cli_test 49 | *simple_http_server 50 | *myredis_srv 51 | 52 | pink/src/build_version.cc 53 | 54 | # Tests 55 | pink/test/pink_thread_test 56 | 57 | # Others 58 | pink/tags 59 | pink/third 60 | *.d.* 61 | *.d 62 | -------------------------------------------------------------------------------- /pink/src/pink_epoll.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_PINK_EPOLL_H_ 7 | #define PINK_SRC_PINK_EPOLL_H_ 8 | #include "sys/epoll.h" 9 | 10 | namespace pink { 11 | 12 | struct PinkFiredEvent { 13 | int fd; 14 | int mask; 15 | }; 16 | 17 | class PinkEpoll { 18 | public: 19 | PinkEpoll(); 20 | ~PinkEpoll(); 21 | int PinkAddEvent(const int fd, const int mask); 22 | int PinkDelEvent(const int fd); 23 | int PinkModEvent(const int fd, const int old_mask, const int mask); 24 | 25 | int PinkPoll(const int timeout); 26 | 27 | PinkFiredEvent *firedevent() const { return firedevent_; } 28 | 29 | private: 30 | int epfd_; 31 | struct epoll_event *events_; 32 | int timeout_; 33 | PinkFiredEvent *firedevent_; 34 | }; 35 | 36 | } // namespace pink 37 | #endif // PINK_SRC_PINK_EPOLL_H_ 38 | -------------------------------------------------------------------------------- /pink/include/redis_cli.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | // 6 | #ifndef PINK_INCLUDE_REDIS_CLI_H_ 7 | #define PINK_INCLUDE_REDIS_CLI_H_ 8 | 9 | #include 10 | #include 11 | 12 | namespace pink { 13 | 14 | 15 | typedef std::vector RedisCmdArgsType; 16 | // We can serialize redis command by 2 ways: 17 | // 1. by variable argmuments; 18 | // eg. RedisCli::Serialize(cmd, "set %s %d", "key", 5); 19 | // cmd will be set as the result string; 20 | // 2. by a string vector; 21 | // eg. RedisCli::Serialize(argv, cmd); 22 | // also cmd will be set as the result string. 23 | extern int SerializeRedisCommand(std::string *cmd, const char *format, ...); 24 | extern int SerializeRedisCommand(RedisCmdArgsType argv, std::string *cmd); 25 | 26 | } // namespace pink 27 | 28 | #endif // PINK_INCLUDE_REDIS_CLI_H_ 29 | -------------------------------------------------------------------------------- /pink/src/pink_thread_name.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | #ifndef PINK_THREAD_NAME_H 6 | #define PINK_THREAD_NAME_H 7 | 8 | #include 9 | #include 10 | 11 | namespace pink { 12 | 13 | #if defined(__GLIBC__) && !defined(__APPLE__) && !defined(__ANDROID__) 14 | # if __GLIBC_PREREQ(2, 12) 15 | // has pthread_setname_np(pthread_t, const char*) (2 params) 16 | # define HAS_PTHREAD_SETNAME_NP 1 17 | # endif 18 | #endif 19 | 20 | #ifdef HAS_PTHREAD_SETNAME_NP 21 | inline bool SetThreadName(pthread_t id, const std::string& name) { 22 | //printf ("use pthread_setname_np(%s)\n", name.substr(0, 15).c_str()); 23 | return 0 == pthread_setname_np(id, name.substr(0, 15).c_str()); 24 | } 25 | #else 26 | inline bool SetThreadName(pthread_t id, const std::string& name) { 27 | //printf ("no pthread_setname\n"); 28 | return false; 29 | } 30 | #endif 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /pink/examples/performance/client.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "message.pb.h" 7 | #include "pink/include/pink_cli.h" 8 | #include "pink/include/pink_define.h" 9 | 10 | using namespace pink; 11 | 12 | int main(int argc, char* argv[]) { 13 | if (argc < 3) { 14 | printf ("Usage: ./client ip port\n"); 15 | exit(0); 16 | } 17 | 18 | std::string ip(argv[1]); 19 | int port = atoi(argv[2]); 20 | 21 | PinkCli* cli = NewPbCli(); 22 | 23 | Status s = cli->Connect(ip, port); 24 | if (!s.ok()) { 25 | printf ("Connect (%s:%d) failed, %s\n", ip.c_str(), port, s.ToString().c_str()); 26 | } 27 | for (int i = 0; i < 100000000; i++) { 28 | Ping msg; 29 | msg.set_ping("ping"); 30 | 31 | s = cli->Send((void *)&msg); 32 | if (!s.ok()) { 33 | printf ("Send failed %s\n", s.ToString().c_str()); 34 | break; 35 | } 36 | 37 | Pong req; 38 | s = cli->Recv((void *)&req); 39 | if (!s.ok()) { 40 | printf ("Recv failed %s\n", s.ToString().c_str()); 41 | break; 42 | } 43 | // printf ("Recv (%s)\n", req.pong().c_str()); 44 | 45 | } 46 | cli->Close(); 47 | 48 | delete cli; 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /pink/src/test/pink_thread_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "pink/include/pink_thread.h" 7 | 8 | #include 9 | #include 10 | 11 | #include "gmock/gmock.h" 12 | 13 | using ::testing::AtLeast; 14 | using ::testing::Invoke; 15 | 16 | class MockThread : public pink::Thread { 17 | public: 18 | MOCK_METHOD0(ThreadMain, void*()); 19 | 20 | void* thread_loop() { 21 | while (!should_stop()) { 22 | usleep(500); 23 | } 24 | return nullptr; 25 | } 26 | }; 27 | 28 | TEST(PinkThreadTest, ThreadOps) { 29 | MockThread t; 30 | EXPECT_CALL(t, ThreadMain()) 31 | .Times(AtLeast(1)); 32 | 33 | ON_CALL(t, ThreadMain()) 34 | .WillByDefault(Invoke(&t, &MockThread::thread_loop)); 35 | 36 | EXPECT_EQ(0, t.StartThread()); 37 | 38 | EXPECT_EQ(true, t.is_running()); 39 | 40 | EXPECT_EQ(false, t.should_stop()); 41 | 42 | EXPECT_EQ(0, t.StopThread()); 43 | 44 | EXPECT_EQ(true, t.should_stop()); 45 | 46 | EXPECT_EQ(false, t.is_running()); 47 | } 48 | -------------------------------------------------------------------------------- /pink/examples/myproto_cli.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "myproto.pb.h" 7 | #include "pink/include/pink_cli.h" 8 | #include "pink/include/pink_define.h" 9 | 10 | using namespace pink; 11 | 12 | int main(int argc, char* argv[]) { 13 | if (argc < 3) { 14 | printf ("Usage: ./client ip port\n"); 15 | exit(0); 16 | } 17 | 18 | std::string ip(argv[1]); 19 | int port = atoi(argv[2]); 20 | 21 | PinkCli* cli = NewPbCli(); 22 | 23 | Status s = cli->Connect(ip, port); 24 | if (!s.ok()) { 25 | printf ("Connect (%s:%d) failed, %s\n", ip.c_str(), port, s.ToString().c_str()); 26 | } 27 | printf ("Connect (%s:%d) ok, fd is %d\n", ip.c_str(), port, cli->fd()); 28 | 29 | for (int i = 0; i < 100000; i++) { 30 | myproto::Ping msg; 31 | msg.set_address("127.00000"); 32 | msg.set_port(2222); 33 | 34 | s = cli->Send((void *)&msg); 35 | if (!s.ok()) { 36 | printf("Send failed %s\n", s.ToString().c_str()); 37 | break; 38 | } 39 | 40 | printf("Send sussces\n"); 41 | myproto::PingRes req; 42 | s = cli->Recv((void *)&req); 43 | if (!s.ok()) { 44 | printf ("Recv failed %s\n", s.ToString().c_str()); 45 | break; 46 | } 47 | printf ("Recv res %d mess (%s)\n", req.res(), req.mess().c_str()); 48 | } 49 | cli->Close(); 50 | 51 | delete cli; 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2020, Qihoo360 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /pink/test/gtest/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file contains a list of people who've made non-trivial 2 | # contribution to the Google C++ Testing Framework project. People 3 | # who commit code to the project are encouraged to add their names 4 | # here. Please keep the list sorted by first names. 5 | 6 | Ajay Joshi 7 | Balázs Dán 8 | Bharat Mediratta 9 | Chandler Carruth 10 | Chris Prince 11 | Chris Taylor 12 | Dan Egnor 13 | Eric Roman 14 | Hady Zalek 15 | Jeffrey Yasskin 16 | Jói Sigurðsson 17 | Keir Mierle 18 | Keith Ray 19 | Kenton Varda 20 | Manuel Klimek 21 | Markus Heule 22 | Mika Raento 23 | Miklós Fazekas 24 | Pasi Valminen 25 | Patrick Hanna 26 | Patrick Riley 27 | Peter Kaminski 28 | Preston Jackson 29 | Rainer Klaffenboeck 30 | Russ Cox 31 | Russ Rufer 32 | Sean Mcafee 33 | Sigurður Ásgeirsson 34 | Tracy Bialik 35 | Vadim Berman 36 | Vlad Losev 37 | Zhanyong Wan 38 | -------------------------------------------------------------------------------- /pink/test/gmock/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file contains a list of people who've made non-trivial 2 | # contribution to the Google C++ Mocking Framework project. People 3 | # who commit code to the project are encouraged to add their names 4 | # here. Please keep the list sorted by first names. 5 | 6 | Benoit Sigoure 7 | Bogdan Piloca 8 | Chandler Carruth 9 | Dave MacLachlan 10 | David Anderson 11 | Dean Sturtevant 12 | Gene Volovich 13 | Hal Burch 14 | Jeffrey Yasskin 15 | Jim Keller 16 | Joe Walnes 17 | Jon Wray 18 | Keir Mierle 19 | Keith Ray 20 | Kostya Serebryany 21 | Lev Makhlis 22 | Manuel Klimek 23 | Mario Tanev 24 | Mark Paskin 25 | Markus Heule 26 | Matthew Simmons 27 | Mike Bland 28 | Neal Norwitz 29 | Nermin Ozkiranartli 30 | Owen Carlsen 31 | Paneendra Ba 32 | Paul Menage 33 | Piotr Kaminski 34 | Russ Rufer 35 | Sverre Sundsdal 36 | Takeshi Yoshino 37 | Vadim Berman 38 | Vlad Losev 39 | Wolfgang Klier 40 | Zhanyong Wan 41 | -------------------------------------------------------------------------------- /pink/src/pink_thread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "pink/include/pink_thread.h" 7 | #include "pink/src/pink_thread_name.h" 8 | #include "slash/include/xdebug.h" 9 | #include "pink/include/pink_define.h" 10 | 11 | namespace pink { 12 | 13 | Thread::Thread() 14 | : should_stop_(false), 15 | running_(false), 16 | thread_id_(0) { 17 | } 18 | 19 | Thread::~Thread() { 20 | } 21 | 22 | void* Thread::RunThread(void *arg) { 23 | Thread* thread = reinterpret_cast(arg); 24 | if (!(thread->thread_name().empty())) { 25 | SetThreadName(pthread_self(), thread->thread_name()); 26 | } 27 | thread->ThreadMain(); 28 | return nullptr; 29 | } 30 | 31 | int Thread::StartThread() { 32 | slash::MutexLock l(&running_mu_); 33 | should_stop_ = false; 34 | if (!running_) { 35 | running_ = true; 36 | return pthread_create(&thread_id_, nullptr, RunThread, (void *)this); 37 | } 38 | return 0; 39 | } 40 | 41 | int Thread::StopThread() { 42 | slash::MutexLock l(&running_mu_); 43 | should_stop_ = true; 44 | if (running_) { 45 | running_ = false; 46 | return pthread_join(thread_id_, nullptr); 47 | } 48 | return 0; 49 | } 50 | 51 | int Thread::JoinThread() { 52 | return pthread_join(thread_id_, nullptr); 53 | } 54 | 55 | } // namespace pink 56 | -------------------------------------------------------------------------------- /pink/test/gmock/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /pink/test/gtest/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /pink/src/pink_conn.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include 7 | #include 8 | 9 | #include "slash/include/xdebug.h" 10 | #include "pink/include/pink_conn.h" 11 | #include "pink/include/pink_thread.h" 12 | #include "pink/src/pink_util.h" 13 | 14 | namespace pink { 15 | 16 | PinkConn::PinkConn(const int fd, 17 | const std::string &ip_port, 18 | ServerThread *thread) 19 | : fd_(fd), 20 | ip_port_(ip_port), 21 | is_reply_(false), 22 | #ifdef __ENABLE_SSL 23 | ssl_(nullptr), 24 | #endif 25 | server_thread_(thread) { 26 | gettimeofday(&last_interaction_, nullptr); 27 | } 28 | 29 | PinkConn::~PinkConn() { 30 | #ifdef __ENABLE_SSL 31 | SSL_free(ssl_); 32 | ssl_ = nullptr; 33 | #endif 34 | } 35 | 36 | bool PinkConn::SetNonblock() { 37 | flags_ = Setnonblocking(fd()); 38 | if (flags_ == -1) { 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | #ifdef __ENABLE_SSL 45 | bool PinkConn::CreateSSL(SSL_CTX* ssl_ctx) { 46 | ssl_ = SSL_new(ssl_ctx); 47 | if (!ssl_) { 48 | log_warn("SSL_new() failed"); 49 | return false; 50 | } 51 | 52 | if (SSL_set_fd(ssl_, fd_) == 0) { 53 | log_warn("SSL_set_fd() failed"); 54 | return false; 55 | } 56 | 57 | SSL_set_accept_state(ssl_); 58 | 59 | return true; 60 | } 61 | #endif 62 | 63 | } // namespace pink 64 | -------------------------------------------------------------------------------- /pink/include/pink_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PINK_THREAD_H_ 7 | #define PINK_INCLUDE_PINK_THREAD_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "slash/include/slash_mutex.h" 14 | 15 | namespace pink { 16 | 17 | class Thread { 18 | public: 19 | Thread(); 20 | virtual ~Thread(); 21 | 22 | virtual int StartThread(); 23 | virtual int StopThread(); 24 | int JoinThread(); 25 | 26 | bool should_stop() { 27 | return should_stop_.load(); 28 | } 29 | 30 | void set_should_stop() { 31 | should_stop_.store(true); 32 | } 33 | 34 | bool is_running() { 35 | return running_; 36 | } 37 | 38 | pthread_t thread_id() const { 39 | return thread_id_; 40 | } 41 | 42 | std::string thread_name() const { 43 | return thread_name_; 44 | } 45 | 46 | void set_thread_name(const std::string& name) { 47 | thread_name_ = name; 48 | } 49 | 50 | protected: 51 | std::atomic should_stop_; 52 | 53 | private: 54 | static void* RunThread(void* arg); 55 | virtual void *ThreadMain() = 0; 56 | 57 | slash::Mutex running_mu_; 58 | bool running_; 59 | pthread_t thread_id_; 60 | std::string thread_name_; 61 | 62 | /* 63 | * No allowed copy and copy assign 64 | */ 65 | Thread(const Thread&); 66 | void operator=(const Thread&); 67 | }; 68 | 69 | } // namespace pink 70 | #endif // PINK_INCLUDE_PINK_THREAD_H_ 71 | -------------------------------------------------------------------------------- /pink/include/redis_conn.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_REDIS_CONN_H_ 7 | #define PINK_INCLUDE_REDIS_CONN_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "slash/include/slash_status.h" 14 | #include "pink/include/pink_define.h" 15 | #include "pink/include/pink_conn.h" 16 | 17 | namespace pink { 18 | 19 | typedef std::vector RedisCmdArgsType; 20 | 21 | class RedisConn: public PinkConn { 22 | public: 23 | RedisConn(const int fd, const std::string &ip_port, ServerThread *thread); 24 | virtual ~RedisConn(); 25 | 26 | virtual ReadStatus GetRequest(); 27 | virtual WriteStatus SendReply(); 28 | virtual void WriteResp(const std::string& resp); 29 | 30 | void TryResizeBuffer() override; 31 | 32 | virtual int DealMessage(RedisCmdArgsType& argv, std::string* response) = 0; 33 | 34 | private: 35 | ReadStatus ProcessInputBuffer(); 36 | ReadStatus ProcessMultibulkBuffer(); 37 | ReadStatus ProcessInlineBuffer(); 38 | int FindNextSeparators(); 39 | int GetNextNum(int pos, long *value); 40 | 41 | char* rbuf_; 42 | int rbuf_len_; 43 | int msg_peak_; 44 | RedisCmdArgsType argv_; 45 | 46 | uint32_t wbuf_pos_; 47 | std::string response_; 48 | 49 | // For Redis Protocol parser 50 | int last_read_pos_; 51 | int next_parse_pos_; 52 | int req_type_; 53 | long multibulk_len_; 54 | long bulk_len_; 55 | }; 56 | 57 | } // namespace pink 58 | #endif // PINK_INCLUDE_REDIS_CONN_H_ 59 | -------------------------------------------------------------------------------- /pink/test/gtest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | printf("Running main() from gtest_main.cc\n"); 36 | testing::InitGoogleTest(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /pink/include/pink_cli.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PINK_CLI_H_ 7 | #define PINK_INCLUDE_PINK_CLI_H_ 8 | 9 | #include 10 | 11 | #include "slash/include/slash_status.h" 12 | 13 | using slash::Status; 14 | 15 | namespace pink { 16 | 17 | class PinkCli { 18 | public: 19 | explicit PinkCli(const std::string& ip = "", const int port = 0); 20 | virtual ~PinkCli(); 21 | 22 | Status Connect(const std::string& bind_ip = ""); 23 | Status Connect(const std::string &peer_ip, const int peer_port, 24 | const std::string& bind_ip = ""); 25 | // Check whether the connection got fin from peer or not 26 | virtual int CheckAliveness(void); 27 | // Compress and write the message 28 | virtual Status Send(void *msg) = 0; 29 | 30 | // Read, parse and store the reply 31 | virtual Status Recv(void *result = NULL) = 0; 32 | 33 | void Close(); 34 | 35 | // TODO(baotiao): delete after redis_cli use RecvRaw 36 | int fd() const; 37 | 38 | bool Available() const; 39 | 40 | // default connect timeout is 1000ms 41 | int set_send_timeout(int send_timeout); 42 | int set_recv_timeout(int recv_timeout); 43 | void set_connect_timeout(int connect_timeout); 44 | 45 | protected: 46 | Status SendRaw(void* buf, size_t len); 47 | Status RecvRaw(void* buf, size_t* len); 48 | 49 | private: 50 | struct Rep; 51 | Rep* rep_; 52 | int set_tcp_nodelay(); 53 | 54 | PinkCli(const PinkCli&); 55 | void operator=(const PinkCli&); 56 | }; 57 | 58 | extern PinkCli *NewPbCli( 59 | const std::string& peer_ip = "", 60 | const int peer_port = 0); 61 | 62 | extern PinkCli *NewRedisCli(); 63 | 64 | } // namespace pink 65 | #endif // PINK_INCLUDE_PINK_CLI_H_ 66 | -------------------------------------------------------------------------------- /pink/examples/Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | LDFLAGS= -lpthread -lrt -lprotobuf 3 | CXXFLAGS=-O2 -std=c++11 -fno-builtin-memcmp -msse -msse4.2 4 | 5 | .PHONY: clean all 6 | 7 | all: bg_thread http_server mydispatch_srv myholy_srv myholy_srv_chandle myproto_cli \ 8 | redis_cli_test simple_http_server myredis_srv 9 | 10 | ifndef PINK_PATH 11 | $(warning Warning: missing pink path, using default) 12 | PINK_PATH=$(CURDIR)/../.. 13 | endif 14 | PINK_INCLUDE_DIR=$(PINK_PATH) 15 | PINK_LIBRARY=$(PINK_PATH)/pink/lib/libpink.a 16 | 17 | ifndef SLASH_PATH 18 | $(warning Warning: missing slash path, using default) 19 | SLASH_PATH=$(CURDIR)/../third/slash 20 | endif 21 | SLASH_INCLUDE_DIR=$(SLASH_PATH) 22 | SLASH_LIBRARY=$(SLASH_PATH)/slash/lib/libslash.a 23 | 24 | CXXFLAGS+= -I$(PINK_INCLUDE_DIR) -I$(SLASH_INCLUDE_DIR) 25 | 26 | DEP_LIBS = $(PINK_LIBRARY) $(SLASH_LIBRARY) 27 | LDFLAGS := $(DEP_LIBS) $(LDFLAGS) 28 | 29 | bg_thread: bg_thread.cc 30 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 31 | 32 | http_server: http_server.cc 33 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 34 | 35 | https_server: https_server.cc 36 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 37 | 38 | mydispatch_srv: mydispatch_srv.cc myproto.pb.cc 39 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 40 | 41 | myholy_srv: myholy_srv.cc myproto.pb.cc 42 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 43 | 44 | myholy_srv_chandle: myholy_srv_chandle.cc myproto.pb.cc 45 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 46 | 47 | myproto_cli: myproto_cli.cc myproto.pb.cc 48 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 49 | 50 | redis_cli_test: redis_cli_test.cc 51 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 52 | 53 | simple_http_server: simple_http_server.cc 54 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 55 | 56 | myredis_srv: myredis_srv.cc 57 | $(CXX) $(CXXFLAGS) $^ -o$@ $(LDFLAGS) 58 | 59 | myproto.pb.cc: myproto.proto 60 | protoc -I=. --cpp_out=. ./$^ 61 | 62 | clean: 63 | find . -name "*.[oda]" -exec rm -f {} \; 64 | rm -rf ./bg_thread ./http_server ./https_server ./mydispatch_srv ./myholy_srv \ 65 | ./myholy_srv_chandle ./myproto_cli ./redis_cli_test ./simple_http_server 66 | -------------------------------------------------------------------------------- /pink/test/gtest/include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of 34 | // OsStackTraceGetterInterface. 35 | // 36 | // ** Custom implementation starts here ** 37 | 38 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 39 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 40 | 41 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 42 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/internal/custom/gmock-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // ============================================================ 31 | // An installation-specific extension point for gmock-matchers.h. 32 | // ============================================================ 33 | // 34 | // Adds google3 callback support to CallableTraits. 35 | // 36 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ 37 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ 38 | 39 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ 40 | -------------------------------------------------------------------------------- /pink/include/bg_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_BG_THREAD_H_ 7 | #define PINK_INCLUDE_BG_THREAD_H_ 8 | 9 | #include 10 | #include 11 | 12 | #include "pink/include/pink_thread.h" 13 | 14 | #include "slash/include/slash_mutex.h" 15 | 16 | namespace pink { 17 | 18 | struct TimerItem { 19 | uint64_t exec_time; 20 | void (*function)(void *); 21 | void* arg; 22 | TimerItem(uint64_t _exec_time, void (*_function)(void*), void* _arg) : 23 | exec_time(_exec_time), 24 | function(_function), 25 | arg(_arg) {} 26 | bool operator < (const TimerItem& item) const { 27 | return exec_time > item.exec_time; 28 | } 29 | }; 30 | 31 | class BGThread : public Thread { 32 | public: 33 | explicit BGThread(int full = 100000) : 34 | Thread::Thread(), 35 | full_(full), 36 | mu_(), 37 | rsignal_(&mu_), 38 | wsignal_(&mu_) { 39 | } 40 | 41 | virtual ~BGThread() { 42 | StopThread(); 43 | } 44 | 45 | virtual int StopThread() override { 46 | should_stop_ = true; 47 | rsignal_.Signal(); 48 | wsignal_.Signal(); 49 | return Thread::StopThread(); 50 | } 51 | 52 | void Schedule(void (*function)(void*), void* arg); 53 | 54 | /* 55 | * timeout is in millionsecond 56 | */ 57 | void DelaySchedule(uint64_t timeout, void (*function)(void *), void* arg); 58 | 59 | void QueueSize(int* pri_size, int* qu_size); 60 | void QueueClear(); 61 | void SwallowReadyTasks(); 62 | 63 | private: 64 | 65 | struct BGItem { 66 | void (*function)(void*); 67 | void* arg; 68 | BGItem(void (*_function)(void*), void* _arg) 69 | : function(_function), arg(_arg) {} 70 | }; 71 | 72 | std::queue queue_; 73 | std::priority_queue timer_queue_; 74 | 75 | size_t full_; 76 | slash::Mutex mu_; 77 | slash::CondVar rsignal_; 78 | slash::CondVar wsignal_; 79 | virtual void *ThreadMain() override; 80 | }; 81 | 82 | } // namespace pink 83 | #endif // PINK_INCLUDE_BG_THREAD_H_ 84 | -------------------------------------------------------------------------------- /pink/test/gtest/include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // See documentation at gtest/gtest-printers.h for details on how to define a 35 | // custom printer. 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /pink/test/gmock/src/gmock-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Mocking Framework (Google Mock) 33 | // 34 | // This file #includes all Google Mock implementation .cc files. The 35 | // purpose is to allow a user to build Google Mock by compiling this 36 | // file alone. 37 | 38 | // This line ensures that gmock.h can be compiled on its own, even 39 | // when it's fused. 40 | #include "gmock/gmock.h" 41 | 42 | // The following lines pull in the real gmock *.cc files. 43 | #include "src/gmock-cardinalities.cc" 44 | #include "src/gmock-internal-utils.cc" 45 | #include "src/gmock-matchers.cc" 46 | #include "src/gmock-spec-builders.cc" 47 | #include "src/gmock.cc" 48 | -------------------------------------------------------------------------------- /pink/test/gtest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/internal/custom/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // Flag related macros: 34 | // GMOCK_DECLARE_bool_(name) 35 | // GMOCK_DECLARE_int32_(name) 36 | // GMOCK_DECLARE_string_(name) 37 | // GMOCK_DEFINE_bool_(name, default_val, doc) 38 | // GMOCK_DEFINE_int32_(name, default_val, doc) 39 | // GMOCK_DEFINE_string_(name, default_val, doc) 40 | // 41 | // ** Custom implementation starts here ** 42 | 43 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 44 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 45 | 46 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 47 | -------------------------------------------------------------------------------- /pink/src/server_socket.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_SERVER_SOCKET_H_ 7 | #define PINK_SRC_SERVER_SOCKET_H_ 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace pink { 16 | 17 | class ServerSocket { 18 | public: 19 | explicit ServerSocket(int port, bool is_block = false); 20 | 21 | virtual ~ServerSocket(); 22 | 23 | /* 24 | * Listen to a specific ip addr on a multi eth machine 25 | * Return 0 if Listen success, <0 other wise 26 | */ 27 | int Listen(const std::string &bind_ip = std::string()); 28 | 29 | void Close(); 30 | 31 | /* 32 | * The get and set functions 33 | */ 34 | void set_port(int port) { 35 | port_ = port; 36 | } 37 | 38 | int port() { 39 | return port_; 40 | } 41 | 42 | void set_keep_alive(bool keep_alive) { 43 | keep_alive_ = keep_alive; 44 | } 45 | bool keep_alive() const { 46 | return keep_alive_; 47 | } 48 | 49 | void set_send_timeout(int send_timeout) { 50 | send_timeout_ = send_timeout; 51 | } 52 | int send_timeout() const { 53 | return send_timeout_; 54 | } 55 | 56 | void set_recv_timeout(int recv_timeout) { 57 | recv_timeout_ = recv_timeout; 58 | } 59 | 60 | int recv_timeout() const { 61 | return recv_timeout_; 62 | } 63 | 64 | int sockfd() const { 65 | return sockfd_; 66 | } 67 | 68 | void set_sockfd(int sockfd) { 69 | sockfd_ = sockfd; 70 | } 71 | 72 | private: 73 | int SetNonBlock(); 74 | /* 75 | * The tcp server port and address 76 | */ 77 | int port_; 78 | int flags_; 79 | int send_timeout_; 80 | int recv_timeout_; 81 | int accept_timeout_; 82 | int accept_backlog_; 83 | int tcp_send_buffer_; 84 | int tcp_recv_buffer_; 85 | bool keep_alive_; 86 | bool listening_; 87 | bool is_block_; 88 | 89 | struct sockaddr_in servaddr_; 90 | int sockfd_; 91 | 92 | /* 93 | * No allowed copy and copy assign operator 94 | */ 95 | 96 | ServerSocket(const ServerSocket&); 97 | void operator=(const ServerSocket&); 98 | }; 99 | 100 | } // namespace pink 101 | 102 | #endif // PINK_SRC_SERVER_SOCKET_H_ 103 | -------------------------------------------------------------------------------- /pink/src/server_socket.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "pink/src/server_socket.h" 17 | #include "pink/src/pink_util.h" 18 | #include "pink/include/pink_define.h" 19 | 20 | namespace pink { 21 | 22 | ServerSocket::ServerSocket(int port, bool is_block) 23 | : port_(port), 24 | send_timeout_(0), 25 | recv_timeout_(0), 26 | accept_timeout_(0), 27 | accept_backlog_(1024), 28 | tcp_send_buffer_(0), 29 | tcp_recv_buffer_(0), 30 | keep_alive_(false), 31 | listening_(false), 32 | is_block_(is_block) { 33 | } 34 | 35 | ServerSocket::~ServerSocket() { 36 | Close(); 37 | } 38 | 39 | /* 40 | * Listen to a specific ip addr on a multi eth machine 41 | * Return 0 if Listen success, other wise 42 | */ 43 | int ServerSocket::Listen(const std::string &bind_ip) { 44 | int ret = 0; 45 | sockfd_ = socket(AF_INET, SOCK_STREAM, 0); 46 | memset(&servaddr_, 0, sizeof(servaddr_)); 47 | 48 | int yes = 1; 49 | ret = setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); 50 | if (ret < 0) { 51 | return kSetSockOptError; 52 | } 53 | 54 | servaddr_.sin_family = AF_INET; 55 | if (bind_ip.empty()) { 56 | servaddr_.sin_addr.s_addr = htonl(INADDR_ANY); 57 | } else { 58 | servaddr_.sin_addr.s_addr = inet_addr(bind_ip.c_str()); 59 | } 60 | servaddr_.sin_port = htons(port_); 61 | 62 | fcntl(sockfd_, F_SETFD, fcntl(sockfd_, F_GETFD) | FD_CLOEXEC); 63 | 64 | ret = bind(sockfd_, (struct sockaddr *) &servaddr_, sizeof(servaddr_)); 65 | if (ret < 0) { 66 | return kBindError; 67 | } 68 | ret = listen(sockfd_, accept_backlog_); 69 | if (ret < 0) { 70 | return kListenError; 71 | } 72 | listening_ = true; 73 | 74 | if (is_block_ == false) { 75 | SetNonBlock(); 76 | } 77 | return kSuccess; 78 | } 79 | 80 | int ServerSocket::SetNonBlock() { 81 | flags_ = Setnonblocking(sockfd()); 82 | if (flags_ == -1) { 83 | return -1; 84 | } 85 | return 0; 86 | } 87 | 88 | void ServerSocket::Close() { 89 | close(sockfd_); 90 | } 91 | 92 | } // namespace pink 93 | -------------------------------------------------------------------------------- /pink/test/gtest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Testing Framework definitions useful in production code. 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void MyMethod(); 44 | // FRIEND_TEST(MyClassTest, MyMethod); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, MyMethod) { 52 | // // Can call MyClass::MyMethod() here. 53 | // } 54 | 55 | #define FRIEND_TEST(test_case_name, test_name)\ 56 | friend class test_case_name##_##test_name##_Test 57 | 58 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 59 | -------------------------------------------------------------------------------- /pink/include/pink_define.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PINK_DEFINE_H_ 7 | #define PINK_INCLUDE_PINK_DEFINE_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace pink { 14 | 15 | #define PINK_MAX_CLIENTS 10240 16 | #define PINK_MAX_MESSAGE 1024 17 | #define PINK_NAME_LEN 1024 18 | 19 | const int kProtoMaxMessage = 64 * 1024 * 1024; // 64MB 20 | 21 | /* 22 | * The pb head and code length 23 | */ 24 | #define COMMAND_HEADER_LENGTH 4 25 | #define COMMAND_CODE_LENGTH 4 26 | 27 | const int kCommandHeaderLength = 4; 28 | 29 | /* 30 | * The socket block type 31 | */ 32 | enum BlockType { 33 | kBlock = 0, 34 | kNonBlock = 1, 35 | }; 36 | 37 | enum EventStatus { 38 | kNone = 0, 39 | kReadable = 1, 40 | kWriteable = 2, 41 | }; 42 | 43 | enum ConnStatus { 44 | kHeader = 0, 45 | kPacket = 1, 46 | kComplete = 2, 47 | kBuildObuf = 3, 48 | kWriteObuf = 4, 49 | }; 50 | 51 | enum ReadStatus { 52 | kReadHalf = 0, 53 | kReadAll = 1, 54 | kReadError = 2, 55 | kReadClose = 3, 56 | kFullError = 4, 57 | kParseError = 5, 58 | kDealError = 6, 59 | kOk = 7, 60 | }; 61 | 62 | enum WriteStatus { 63 | kWriteHalf = 0, 64 | kWriteAll = 1, 65 | kWriteError = 2, 66 | }; 67 | 68 | enum RetCode { 69 | kSuccess = 0, 70 | kBindError = 1, 71 | kCreateThreadError = 2, 72 | kListenError = 3, 73 | kSetSockOptError = 4, 74 | }; 75 | 76 | /* 77 | * define the redis protocol 78 | */ 79 | #define REDIS_MAX_MESSAGE (1 << 29) // 512MB 80 | #define REDIS_MBULK_BIG_ARG (1024 * 32) // 32KB 81 | #define DEFAULT_WBUF_SIZE 262144 // 256KB 82 | #define REDIS_INLINE_MAXLEN (1024 * 64) // 64KB 83 | #define REDIS_IOBUF_LEN 16384 // 16KB 84 | #define REDIS_REQ_INLINE 1 85 | #define REDIS_REQ_MULTIBULK 2 86 | 87 | /* 88 | * define the pink cron interval (ms) 89 | */ 90 | #define PINK_CRON_INTERVAL 1000 91 | 92 | /* 93 | * define the macro in PINK_conf 94 | */ 95 | 96 | #define PINK_WORD_SIZE 1024 97 | #define PINK_LINE_SIZE 1024 98 | #define PINK_CONF_MAX_NUM 1024 99 | 100 | 101 | /* 102 | * define common character 103 | */ 104 | #define SPACE ' ' 105 | #define COLON ':' 106 | #define SHARP '#' 107 | 108 | } // namespace pink 109 | #endif // PINK_INCLUDE_PINK_DEFINE_H_ 110 | -------------------------------------------------------------------------------- /pink/src/holy_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_HOLY_THREAD_H_ 7 | #define PINK_SRC_HOLY_THREAD_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "slash/include/xdebug.h" 16 | #include "slash/include/slash_mutex.h" 17 | #include "pink/include/server_thread.h" 18 | #include "pink/include/pink_conn.h" 19 | 20 | namespace pink { 21 | class PinkConn; 22 | 23 | class HolyThread: public ServerThread { 24 | public: 25 | // This type thread thread will listen and work self list redis thread 26 | HolyThread(int port, ConnFactory* conn_factory, 27 | int cron_interval = 0, const ServerHandle* handle = nullptr); 28 | HolyThread(const std::string& bind_ip, int port, 29 | ConnFactory* conn_factory, 30 | int cron_interval = 0, const ServerHandle* handle = nullptr); 31 | HolyThread(const std::set& bind_ips, int port, 32 | ConnFactory* conn_factory, 33 | int cron_interval = 0, const ServerHandle* handle = nullptr); 34 | virtual ~HolyThread(); 35 | 36 | virtual int StartThread() override; 37 | 38 | virtual int StopThread() override; 39 | 40 | virtual void set_keepalive_timeout(int timeout) override { 41 | keepalive_timeout_ = timeout; 42 | } 43 | 44 | virtual int conn_num() const override; 45 | 46 | virtual std::vector conns_info() const override; 47 | 48 | virtual PinkConn* MoveConnOut(int fd) override; 49 | 50 | virtual void KillAllConns() override; 51 | 52 | virtual bool KillConn(const std::string& ip_port) override; 53 | 54 | private: 55 | mutable slash::RWMutex rwlock_; /* For external statistics */ 56 | std::map conns_; 57 | 58 | ConnFactory *conn_factory_; 59 | void* private_data_; 60 | 61 | std::atomic keepalive_timeout_; // keepalive second 62 | 63 | void DoCronTask() override; 64 | 65 | slash::Mutex killer_mutex_; 66 | std::set deleting_conn_ipport_; 67 | 68 | void HandleNewConn(int connfd, const std::string &ip_port) override; 69 | void HandleConnEvent(PinkFiredEvent *pfe) override; 70 | 71 | void CloseFd(PinkConn* conn); 72 | void Cleanup(); 73 | }; // class HolyThread 74 | 75 | 76 | } // namespace pink 77 | #endif // PINK_SRC_HOLY_THREAD_H_ 78 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/gmock-more-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: marcus.boerger@google.com (Marcus Boerger) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file implements some matchers that depend on gmock-generated-matchers.h. 35 | // 36 | // Note that tests are implemented in gmock-matchers_test.cc rather than 37 | // gmock-more-matchers-test.cc. 38 | 39 | #ifndef GMOCK_GMOCK_MORE_MATCHERS_H_ 40 | #define GMOCK_GMOCK_MORE_MATCHERS_H_ 41 | 42 | #include "gmock/gmock-generated-matchers.h" 43 | 44 | namespace testing { 45 | 46 | // Defines a matcher that matches an empty container. The container must 47 | // support both size() and empty(), which all STL-like containers provide. 48 | MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { 49 | if (arg.empty()) { 50 | return true; 51 | } 52 | *result_listener << "whose size is " << arg.size(); 53 | return false; 54 | } 55 | 56 | } // namespace testing 57 | 58 | #endif // GMOCK_GMOCK_MORE_MATCHERS_H_ 59 | -------------------------------------------------------------------------------- /pink/include/pb_conn.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PB_CONN_H_ 7 | #define PINK_INCLUDE_PB_CONN_H_ 8 | 9 | #include 10 | #include 11 | 12 | #include "google/protobuf/message.h" 13 | #include "slash/include/slash_status.h" 14 | #include "pink/include/pink_conn.h" 15 | #include "pink/include/pink_define.h" 16 | 17 | namespace pink { 18 | 19 | using slash::Status; 20 | 21 | class PbConn: public PinkConn { 22 | public: 23 | PbConn(const int fd, const std::string &ip_port, ServerThread *thread); 24 | virtual ~PbConn(); 25 | 26 | ReadStatus GetRequest() override; 27 | WriteStatus SendReply() override; 28 | 29 | /* 30 | * The Variable need by read the buf, 31 | * We allocate the memory when we start the server 32 | */ 33 | uint32_t header_len_; 34 | char* rbuf_; 35 | uint32_t cur_pos_; 36 | uint32_t rbuf_len_; 37 | int32_t remain_packet_len_; 38 | 39 | ConnStatus connStatus_; 40 | 41 | google::protobuf::Message *res_; 42 | 43 | protected: 44 | // NOTE: if this function return non 0, the the server will close this connection 45 | // 46 | // In the implementation of DealMessage, we should distinguish two types of error 47 | // 48 | // 1. protocol parsing error 49 | // 2. service logic error 50 | // 51 | // protocol parsing error means that we receive a message that is not 52 | // a protobuf message that we know, 53 | // in this situation we should close this connection. 54 | // why we should close connection? 55 | // beacause if we parse protocol error, it means that the content in this 56 | // connection can't not be parse, we can't recognize the next message. 57 | // The only thing we can do is close this connection. 58 | // in this condition the DealMessage should return -1; 59 | // 60 | // 61 | // the logic error means that we have receive the message, and the 62 | // message is protobuf message that we define in proto file. 63 | // After receiving this message, we start execute our service logic. 64 | // the service logic error we should put it in res_, and return 0 65 | // since this is the service logic error, not the network error. 66 | // this connection we can use again. 67 | // 68 | virtual int DealMessage() = 0; 69 | 70 | private: 71 | char* wbuf_; 72 | uint32_t wbuf_len_; 73 | uint32_t wbuf_pos_; 74 | virtual Status BuildObuf(); 75 | }; 76 | 77 | } // namespace pink 78 | #endif // PINK_INCLUDE_PB_CONN_H_ 79 | -------------------------------------------------------------------------------- /pink/examples/mydispatch_srv.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "slash/include/xdebug.h" 7 | #include "pink/include/pink_thread.h" 8 | #include "pink/include/server_thread.h" 9 | 10 | #include "myproto.pb.h" 11 | #include "pink/include/pb_conn.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace pink; 18 | 19 | class MyConn: public PbConn { 20 | public: 21 | MyConn(int fd, const std::string& ip_port, ServerThread *thread, 22 | void* worker_specific_data); 23 | virtual ~MyConn(); 24 | protected: 25 | virtual int DealMessage(); 26 | 27 | private: 28 | myproto::Ping ping_; 29 | myproto::PingRes ping_res_; 30 | }; 31 | 32 | MyConn::MyConn(int fd, const std::string& ip_port, ServerThread *thread, 33 | void* worker_specific_data) 34 | : PbConn(fd, ip_port, thread) { 35 | // Handle worker_specific_data ... 36 | } 37 | 38 | MyConn::~MyConn() { 39 | } 40 | 41 | int MyConn::DealMessage() { 42 | printf("In the myconn DealMessage branch\n"); 43 | ping_.ParseFromArray(rbuf_ + cur_pos_ - header_len_, header_len_); 44 | ping_res_.Clear(); 45 | ping_res_.set_res(11234); 46 | ping_res_.set_mess("heiheidfdfdf"); 47 | printf ("DealMessage receive (%s)\n", ping_res_.mess().c_str()); 48 | res_ = &ping_res_; 49 | set_is_reply(true); 50 | return 0; 51 | } 52 | 53 | class MyConnFactory : public ConnFactory { 54 | public: 55 | virtual PinkConn *NewPinkConn(int connfd, const std::string &ip_port, 56 | ServerThread *thread, 57 | void* worker_specific_data) const { 58 | return new MyConn(connfd, ip_port, thread, worker_specific_data); 59 | } 60 | }; 61 | 62 | static std::atomic running(false); 63 | 64 | static void IntSigHandle(const int sig) { 65 | printf("Catch Signal %d, cleanup...\n", sig); 66 | running.store(false); 67 | printf("server Exit"); 68 | } 69 | 70 | static void SignalSetup() { 71 | signal(SIGHUP, SIG_IGN); 72 | signal(SIGPIPE, SIG_IGN); 73 | signal(SIGINT, &IntSigHandle); 74 | signal(SIGQUIT, &IntSigHandle); 75 | signal(SIGTERM, &IntSigHandle); 76 | } 77 | 78 | int main() { 79 | SignalSetup(); 80 | ConnFactory *my_conn_factory = new MyConnFactory(); 81 | ServerThread *st = NewDispatchThread(9211, 10, my_conn_factory, 1000); 82 | 83 | if (st->StartThread() != 0) { 84 | printf("StartThread error happened!\n"); 85 | exit(-1); 86 | } 87 | running.store(true); 88 | while (running.load()) { 89 | sleep(1); 90 | } 91 | st->StopThread(); 92 | 93 | delete st; 94 | delete my_conn_factory; 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /pink/src/pink_epoll.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "pink/src/pink_epoll.h" 7 | 8 | #include 9 | #include 10 | 11 | #include "pink/include/pink_define.h" 12 | #include "slash/include/xdebug.h" 13 | 14 | namespace pink { 15 | 16 | static const int kPinkMaxClients = 10240; 17 | 18 | PinkEpoll::PinkEpoll() : timeout_(1000) { 19 | #if defined(EPOLL_CLOEXEC) 20 | epfd_ = epoll_create1(EPOLL_CLOEXEC); 21 | #else 22 | epfd_ = epoll_create(1024); 23 | #endif 24 | 25 | fcntl(epfd_, F_SETFD, fcntl(epfd_, F_GETFD) | FD_CLOEXEC); 26 | 27 | if (epfd_ < 0) { 28 | log_err("epoll create fail"); 29 | exit(1); 30 | } 31 | events_ = (struct epoll_event *)malloc( 32 | sizeof(struct epoll_event) * kPinkMaxClients); 33 | 34 | firedevent_ = reinterpret_cast(malloc( 35 | sizeof(PinkFiredEvent) * kPinkMaxClients)); 36 | } 37 | 38 | PinkEpoll::~PinkEpoll() { 39 | free(firedevent_); 40 | free(events_); 41 | close(epfd_); 42 | } 43 | 44 | int PinkEpoll::PinkAddEvent(const int fd, const int mask) { 45 | struct epoll_event ee; 46 | ee.data.fd = fd; 47 | ee.events = mask; 48 | return epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ee); 49 | } 50 | 51 | int PinkEpoll::PinkModEvent(const int fd, const int old_mask, const int mask) { 52 | struct epoll_event ee; 53 | ee.data.fd = fd; 54 | ee.events = (old_mask | mask); 55 | return epoll_ctl(epfd_, EPOLL_CTL_MOD, fd, &ee); 56 | } 57 | 58 | int PinkEpoll::PinkDelEvent(const int fd) { 59 | /* 60 | * Kernel < 2.6.9 need a non null event point to EPOLL_CTL_DEL 61 | */ 62 | struct epoll_event ee; 63 | ee.data.fd = fd; 64 | return epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, &ee); 65 | } 66 | 67 | int PinkEpoll::PinkPoll(const int timeout) { 68 | int retval, numevents = 0; 69 | retval = epoll_wait(epfd_, events_, PINK_MAX_CLIENTS, timeout); 70 | if (retval > 0) { 71 | numevents = retval; 72 | for (int i = 0; i < numevents; i++) { 73 | int mask = 0; 74 | firedevent_[i].fd = (events_ + i)->data.fd; 75 | 76 | if ((events_ + i)->events & EPOLLIN) { 77 | mask |= EPOLLIN; 78 | } 79 | if ((events_ + i)->events & EPOLLOUT) { 80 | mask |= EPOLLOUT; 81 | } 82 | if ((events_ + i)->events & EPOLLERR) { 83 | mask |= EPOLLERR; 84 | } 85 | if ((events_ + i)->events & EPOLLHUP) { 86 | mask |= EPOLLHUP; 87 | } 88 | firedevent_[i].mask = mask; 89 | } 90 | } 91 | return numevents; 92 | } 93 | 94 | } // namespace pink 95 | -------------------------------------------------------------------------------- /pink/test/gmock/src/gmock_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include 33 | #include "gmock/gmock.h" 34 | #include "gtest/gtest.h" 35 | 36 | // MS C++ compiler/linker has a bug on Windows (not on Windows CE), which 37 | // causes a link error when _tmain is defined in a static library and UNICODE 38 | // is enabled. For this reason instead of _tmain, main function is used on 39 | // Windows. See the following link to track the current status of this bug: 40 | // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=394464 // NOLINT 41 | #if GTEST_OS_WINDOWS_MOBILE 42 | # include // NOLINT 43 | 44 | GTEST_API_ int _tmain(int argc, TCHAR** argv) { 45 | #else 46 | GTEST_API_ int main(int argc, char** argv) { 47 | #endif // GTEST_OS_WINDOWS_MOBILE 48 | std::cout << "Running main() from gmock_main.cc\n"; 49 | // Since Google Mock depends on Google Test, InitGoogleMock() is 50 | // also responsible for initializing Google Test. Therefore there's 51 | // no need for calling testing::InitGoogleTest() separately. 52 | testing::InitGoogleMock(&argc, argv); 53 | return RUN_ALL_TESTS(); 54 | } 55 | -------------------------------------------------------------------------------- /pink/src/dispatch_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_DISPATCH_THREAD_H_ 7 | #define PINK_SRC_DISPATCH_THREAD_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "slash/include/xdebug.h" 16 | #include "pink/include/server_thread.h" 17 | 18 | namespace pink { 19 | 20 | class PinkItem; 21 | class PinkFiredEvent; 22 | class WorkerThread; 23 | 24 | class DispatchThread : public ServerThread { 25 | public: 26 | DispatchThread(int port, 27 | int work_num, ConnFactory* conn_factory, 28 | int cron_interval, 29 | int queue_limit, 30 | const ServerHandle* handle); 31 | DispatchThread(const std::string &ip, int port, 32 | int work_num, ConnFactory* conn_factory, 33 | int cron_interval, 34 | int queue_limit, 35 | const ServerHandle* handle); 36 | DispatchThread(const std::set& ips, int port, 37 | int work_num, ConnFactory* conn_factory, 38 | int cron_interval, 39 | int queue_limit, 40 | const ServerHandle* handle); 41 | 42 | virtual ~DispatchThread(); 43 | 44 | virtual int StartThread() override; 45 | 46 | virtual int StopThread() override; 47 | 48 | virtual void set_keepalive_timeout(int timeout) override; 49 | 50 | virtual int conn_num() const override; 51 | 52 | virtual std::vector conns_info() const override; 53 | 54 | virtual PinkConn* MoveConnOut(int fd) override; 55 | 56 | virtual void KillAllConns() override; 57 | 58 | virtual bool KillConn(const std::string& ip_port) override; 59 | 60 | void HandleNewConn(const int connfd, const std::string& ip_port) override; 61 | 62 | void SetQueueLimit(int queue_limit) override; 63 | private: 64 | /* 65 | * Here we used auto poll to find the next work thread, 66 | * last_thread_ is the last work thread 67 | */ 68 | int last_thread_; 69 | int work_num_; 70 | /* 71 | * This is the work threads 72 | */ 73 | WorkerThread** worker_thread_; 74 | int queue_limit_; 75 | std::map localdata_; 76 | 77 | void HandleConnEvent(PinkFiredEvent *pfe) override { 78 | UNUSED(pfe); 79 | } 80 | 81 | // No copying allowed 82 | DispatchThread(const DispatchThread&); 83 | void operator=(const DispatchThread&); 84 | }; // class DispatchThread 85 | 86 | } // namespace pink 87 | #endif // PINK_SRC_DISPATCH_THREAD_H_ 88 | -------------------------------------------------------------------------------- /pink/src/pb_cli.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "slash/include/xdebug.h" 12 | #include "pink/include/pink_cli.h" 13 | #include "pink/include/pink_define.h" 14 | 15 | namespace pink { 16 | 17 | // Default PBCli is block IO; 18 | class PbCli : public PinkCli { 19 | public: 20 | PbCli(const std::string& ip, const int port); 21 | virtual ~PbCli(); 22 | 23 | // msg should have been parsed 24 | virtual Status Send(void *msg_req) override; 25 | 26 | // Read, parse and store the reply 27 | virtual Status Recv(void *msg_res) override; 28 | 29 | 30 | private: 31 | // BuildWbuf need to access rbuf_, wbuf_; 32 | char *rbuf_; 33 | char *wbuf_; 34 | 35 | PbCli(const PbCli&); 36 | void operator= (const PbCli&); 37 | }; 38 | 39 | PbCli::PbCli(const std::string& ip, const int port) 40 | : PinkCli(ip, port) { 41 | rbuf_ = reinterpret_cast(malloc(sizeof(char) * kProtoMaxMessage)); 42 | wbuf_ = reinterpret_cast(malloc(sizeof(char) * kProtoMaxMessage)); 43 | } 44 | 45 | PbCli::~PbCli() { 46 | free(wbuf_); 47 | free(rbuf_); 48 | } 49 | 50 | Status PbCli::Send(void *msg) { 51 | google::protobuf::Message *req = 52 | reinterpret_cast(msg); 53 | 54 | int wbuf_len = req->ByteSize(); 55 | req->SerializeToArray(wbuf_ + kCommandHeaderLength, wbuf_len); 56 | uint32_t len = htonl(wbuf_len); 57 | memcpy(wbuf_, &len, sizeof(uint32_t)); 58 | wbuf_len += kCommandHeaderLength; 59 | 60 | return PinkCli::SendRaw(wbuf_, wbuf_len); 61 | } 62 | 63 | Status PbCli::Recv(void *msg_res) { 64 | google::protobuf::Message *res = 65 | reinterpret_cast(msg_res); 66 | 67 | // Read Header 68 | size_t read_len = kCommandHeaderLength; 69 | Status s = RecvRaw(reinterpret_cast(rbuf_), &read_len); 70 | if (!s.ok()) { 71 | return s; 72 | } 73 | 74 | uint32_t integer; 75 | memcpy(reinterpret_cast(&integer), rbuf_, sizeof(uint32_t)); 76 | size_t packet_len = ntohl(integer); 77 | 78 | // Read Packet 79 | s = RecvRaw(reinterpret_cast(rbuf_), &packet_len); 80 | if (!s.ok()) { 81 | return s; 82 | } 83 | 84 | if (!res->ParseFromArray(rbuf_ , packet_len)) { 85 | return Status::Corruption("PbCli::Recv Protobuf ParseFromArray error"); 86 | } 87 | return Status::OK(); 88 | } 89 | 90 | PinkCli *NewPbCli(const std::string& peer_ip, const int peer_port) { 91 | return new PbCli(peer_ip, peer_port); 92 | } 93 | 94 | } // namespace pink 95 | -------------------------------------------------------------------------------- /pink/src/worker_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_SRC_WORKER_THREAD_H_ 7 | #define PINK_SRC_WORKER_THREAD_H_ 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "slash/include/xdebug.h" 20 | #include "slash/include/slash_mutex.h" 21 | 22 | #include "pink/include/server_thread.h" 23 | #include "pink/src/pink_epoll.h" 24 | #include "pink/include/pink_thread.h" 25 | #include "pink/include/pink_define.h" 26 | 27 | namespace pink { 28 | 29 | class PinkItem; 30 | class PinkEpoll; 31 | class PinkFiredEvent; 32 | class PinkConn; 33 | class ConnFactory; 34 | 35 | class WorkerThread : public Thread { 36 | public: 37 | explicit WorkerThread(ConnFactory *conn_factory, ServerThread* server_thread, 38 | int cron_interval = 0); 39 | 40 | virtual ~WorkerThread(); 41 | 42 | void set_keepalive_timeout(int timeout) { 43 | keepalive_timeout_ = timeout; 44 | } 45 | 46 | int conn_num() const; 47 | 48 | std::vector conns_info() const; 49 | 50 | PinkConn* MoveConnOut(int fd); 51 | 52 | /* 53 | * The PbItem queue is the fd queue, receive from dispatch thread 54 | */ 55 | std::queue conn_queue_; 56 | 57 | int notify_receive_fd() { 58 | return notify_receive_fd_; 59 | } 60 | int notify_send_fd() { 61 | return notify_send_fd_; 62 | } 63 | PinkEpoll* pink_epoll() { 64 | return pink_epoll_; 65 | } 66 | bool TryKillConn(const std::string& ip_port); 67 | 68 | slash::Mutex mutex_; 69 | 70 | mutable slash::RWMutex rwlock_; /* For external statistics */ 71 | std::map conns_; 72 | 73 | void* private_data_; 74 | 75 | private: 76 | ServerThread* server_thread_; 77 | ConnFactory *conn_factory_; 78 | int cron_interval_; 79 | 80 | /* 81 | * These two fd receive the notify from dispatch thread 82 | */ 83 | int notify_receive_fd_; 84 | int notify_send_fd_; 85 | 86 | /* 87 | * The epoll handler 88 | */ 89 | PinkEpoll *pink_epoll_; 90 | 91 | std::atomic keepalive_timeout_; // keepalive second 92 | 93 | virtual void *ThreadMain() override; 94 | void DoCronTask(); 95 | 96 | slash::Mutex killer_mutex_; 97 | std::set deleting_conn_ipport_; 98 | 99 | // clean conns 100 | void CloseFd(PinkConn* conn); 101 | void Cleanup(); 102 | }; // class WorkerThread 103 | 104 | } // namespace pink 105 | #endif // PINK_SRC_WORKER_THREAD_H_ 106 | -------------------------------------------------------------------------------- /pink/examples/myholy_srv.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pink/include/server_thread.h" 7 | #include "pink/include/pink_conn.h" 8 | #include "pink/include/pb_conn.h" 9 | #include "pink/include/pink_thread.h" 10 | #include "myproto.pb.h" 11 | 12 | using namespace pink; 13 | 14 | class MyConn: public PbConn { 15 | public: 16 | MyConn(int fd, const std::string& ip_port, ServerThread *thread, 17 | void* worker_specific_data); 18 | virtual ~MyConn(); 19 | 20 | protected: 21 | virtual int DealMessage(); 22 | 23 | private: 24 | myproto::Ping ping_; 25 | myproto::PingRes ping_res_; 26 | }; 27 | 28 | MyConn::MyConn(int fd, const std::string& ip_port, 29 | ServerThread *thread, void* worker_specific_data) 30 | : PbConn(fd, ip_port, thread) { 31 | // Handle worker_specific_data ... 32 | } 33 | 34 | MyConn::~MyConn() { 35 | } 36 | 37 | int MyConn::DealMessage() { 38 | printf("In the myconn DealMessage branch\n"); 39 | ping_.ParseFromArray(rbuf_ + cur_pos_ - header_len_, header_len_); 40 | printf ("DealMessage receive (%s) port %d \n", ping_.address().c_str(), ping_.port()); 41 | 42 | ping_res_.Clear(); 43 | ping_res_.set_res(11234); 44 | ping_res_.set_mess("heiheidfdfdf"); 45 | res_ = &ping_res_; 46 | set_is_reply(true); 47 | return 0; 48 | } 49 | 50 | class MyConnFactory : public ConnFactory { 51 | public: 52 | virtual PinkConn *NewPinkConn(int connfd, const std::string &ip_port, 53 | ServerThread *thread, 54 | void* worker_specific_data) const { 55 | return new MyConn(connfd, ip_port, thread, worker_specific_data); 56 | } 57 | }; 58 | 59 | static std::atomic running(false); 60 | 61 | static void IntSigHandle(const int sig) { 62 | printf("Catch Signal %d, cleanup...\n", sig); 63 | running.store(false); 64 | printf("server Exit"); 65 | } 66 | 67 | static void SignalSetup() { 68 | signal(SIGHUP, SIG_IGN); 69 | signal(SIGPIPE, SIG_IGN); 70 | signal(SIGINT, &IntSigHandle); 71 | signal(SIGQUIT, &IntSigHandle); 72 | signal(SIGTERM, &IntSigHandle); 73 | } 74 | 75 | int main(int argc, char* argv[]) { 76 | if (argc < 2) { 77 | printf ("Usage: ./server port\n"); 78 | exit(0); 79 | } 80 | 81 | int my_port = (argc > 1) ? atoi(argv[1]) : 8221; 82 | 83 | SignalSetup(); 84 | 85 | ConnFactory *conn_factory = new MyConnFactory(); 86 | 87 | ServerThread* my_thread = NewHolyThread(my_port, conn_factory); 88 | if (my_thread->StartThread() != 0) { 89 | printf("StartThread error happened!\n"); 90 | exit(-1); 91 | } 92 | running.store(true); 93 | while (running.load()) { 94 | sleep(1); 95 | } 96 | my_thread->StopThread(); 97 | 98 | delete my_thread; 99 | delete conn_factory; 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /pink/examples/performance/server.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "pink/include/server_thread.h" 9 | #include "pink/include/pink_conn.h" 10 | #include "pink/include/pb_conn.h" 11 | #include "pink/include/pink_thread.h" 12 | #include "message.pb.h" 13 | 14 | using namespace pink; 15 | using namespace std; 16 | 17 | uint64_t NowMicros() { 18 | struct timeval tv; 19 | gettimeofday(&tv, NULL); 20 | return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; 21 | } 22 | 23 | static atomic num(0); 24 | 25 | class PingConn : public PbConn { 26 | public: 27 | PingConn(int fd, std::string ip_port, pink::ServerThread* pself_thread = NULL) : 28 | PbConn(fd, ip_port, pself_thread) { 29 | } 30 | virtual ~PingConn() {} 31 | 32 | int DealMessage() { 33 | num++; 34 | request_.ParseFromArray(rbuf_ + cur_pos_ - header_len_, header_len_); 35 | 36 | response_.Clear(); 37 | response_.set_pong("hello " + request_.ping()); 38 | res_ = &response_; 39 | 40 | set_is_reply(true); 41 | 42 | return 0; 43 | } 44 | 45 | private: 46 | 47 | Ping request_; 48 | Pong response_; 49 | 50 | PingConn(PingConn&); 51 | PingConn& operator=(PingConn&); 52 | }; 53 | 54 | 55 | class PingConnFactory : public ConnFactory { 56 | public: 57 | virtual PinkConn *NewPinkConn( 58 | int connfd, 59 | const std::string &ip_port, 60 | ServerThread *thread, 61 | void* worker_specific_data) const { 62 | return new PingConn(connfd, ip_port, thread); 63 | } 64 | }; 65 | 66 | std::atomic should_stop(false); 67 | 68 | static void IntSigHandle(const int sig) { 69 | should_stop.store(true); 70 | } 71 | 72 | static void SignalSetup() { 73 | signal(SIGHUP, SIG_IGN); 74 | signal(SIGPIPE, SIG_IGN); 75 | signal(SIGINT, &IntSigHandle); 76 | signal(SIGQUIT, &IntSigHandle); 77 | signal(SIGTERM, &IntSigHandle); 78 | } 79 | 80 | int main(int argc, char* argv[]) { 81 | if (argc < 2) { 82 | printf ("Usage: ./server ip port\n"); 83 | exit(0); 84 | } 85 | 86 | std::string ip(argv[1]); 87 | int port = atoi(argv[2]); 88 | 89 | PingConnFactory conn_factory; 90 | 91 | SignalSetup(); 92 | 93 | ServerThread *st_thread = NewDispatchThread(ip, port, 24, &conn_factory, 1000); 94 | st_thread->StartThread(); 95 | uint64_t st, ed; 96 | 97 | while (!should_stop) { 98 | st = NowMicros(); 99 | int prv = num.load(); 100 | sleep(1); 101 | printf("num %d\n", num.load()); 102 | ed = NowMicros(); 103 | printf("mmap cost time microsecond(us) %lld\n", ed - st); 104 | printf("average qps %lf\n", (double)(num.load() - prv) / ((double)(ed - st) / 1000000)); 105 | } 106 | st_thread->StopThread(); 107 | 108 | delete st_thread; 109 | 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /pink/include/pink_conn.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PINK_CONN_H_ 7 | #define PINK_INCLUDE_PINK_CONN_H_ 8 | 9 | #include 10 | #include 11 | 12 | #ifdef __ENABLE_SSL 13 | #include 14 | #include 15 | #endif 16 | 17 | #include "pink/include/pink_define.h" 18 | #include "pink/include/server_thread.h" 19 | 20 | namespace pink { 21 | 22 | class Thread; 23 | 24 | class PinkConn { 25 | public: 26 | PinkConn(const int fd, const std::string &ip_port, ServerThread *thread); 27 | virtual ~PinkConn(); 28 | 29 | /* 30 | * Set the fd to nonblock && set the flag_ the the fd flag 31 | */ 32 | bool SetNonblock(); 33 | 34 | #ifdef __ENABLE_SSL 35 | bool CreateSSL(SSL_CTX* ssl_ctx); 36 | #endif 37 | 38 | virtual ReadStatus GetRequest() = 0; 39 | virtual WriteStatus SendReply() = 0; 40 | virtual void WriteResp(const std::string& resp) { } 41 | 42 | virtual void TryResizeBuffer() {} 43 | 44 | int flags() const { 45 | return flags_; 46 | } 47 | 48 | void set_fd(const int fd) { 49 | fd_ = fd; 50 | } 51 | 52 | int fd() const { 53 | return fd_; 54 | } 55 | 56 | std::string ip_port() const { 57 | return ip_port_; 58 | } 59 | 60 | void set_is_reply(const bool is_reply) { 61 | is_reply_ = is_reply; 62 | } 63 | 64 | bool is_reply() const { 65 | return is_reply_; 66 | } 67 | 68 | void set_last_interaction(const struct timeval &now) { 69 | last_interaction_ = now; 70 | } 71 | 72 | struct timeval last_interaction() const { 73 | return last_interaction_; 74 | } 75 | 76 | ServerThread *server_thread() const { 77 | return server_thread_; 78 | } 79 | 80 | #ifdef __ENABLE_SSL 81 | SSL* ssl() { 82 | return ssl_; 83 | } 84 | 85 | bool security() { 86 | return ssl_ != nullptr; 87 | } 88 | #endif 89 | 90 | private: 91 | int fd_; 92 | std::string ip_port_; 93 | bool is_reply_; 94 | struct timeval last_interaction_; 95 | int flags_; 96 | 97 | #ifdef __ENABLE_SSL 98 | SSL* ssl_; 99 | #endif 100 | 101 | // the server thread this conn belong to 102 | ServerThread *server_thread_; 103 | 104 | /* 105 | * No allowed copy and copy assign operator 106 | */ 107 | PinkConn(const PinkConn&); 108 | void operator=(const PinkConn&); 109 | }; 110 | 111 | 112 | /* 113 | * for every conn, we need create a corresponding ConnFactory 114 | */ 115 | class ConnFactory { 116 | public: 117 | virtual ~ConnFactory() {} 118 | virtual PinkConn* NewPinkConn( 119 | int connfd, 120 | const std::string &ip_port, 121 | ServerThread *server_thread, 122 | void* worker_private_data /* Has set in ThreadEnvHandle */) const = 0; 123 | }; 124 | 125 | } // namespace pink 126 | 127 | #endif // PINK_INCLUDE_PINK_CONN_H_ 128 | -------------------------------------------------------------------------------- /pink/examples/simple_http_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "slash/include/slash_status.h" 11 | #include "pink/include/pink_thread.h" 12 | #include "pink/include/server_thread.h" 13 | #include "pink/include/simple_http_conn.h" 14 | 15 | using namespace pink; 16 | 17 | class MyHTTPConn : public pink::SimpleHTTPConn { 18 | public: 19 | MyHTTPConn(const int fd, const std::string& ip_port, ServerThread* worker) : 20 | SimpleHTTPConn(fd, ip_port, worker) { 21 | } 22 | virtual void DealMessage(const pink::Request* req, pink::Response* res) { 23 | std::cout << "handle get"<< std::endl; 24 | std::cout << " + method: " << req->method << std::endl; 25 | std::cout << " + path: " << req->path << std::endl; 26 | std::cout << " + version: " << req->version << std::endl; 27 | std::cout << " + content: " << req->content<< std::endl; 28 | std::cout << " + headers: " << std::endl; 29 | for (auto& h : req->headers) { 30 | std::cout << " + " << h.first << ":" << h.second << std::endl; 31 | } 32 | std::cout << " + query_params: " << std::endl; 33 | for (auto& q : req->query_params) { 34 | std::cout << " + " << q.first << ":" << q.second << std::endl; 35 | } 36 | std::cout << " + post_params: " << std::endl; 37 | for (auto& q : req->post_params) { 38 | std::cout << " + " << q.first << ":" << q.second << std::endl; 39 | } 40 | 41 | res->SetStatusCode(200); 42 | res->SetBody("china"); 43 | } 44 | }; 45 | 46 | class MyConnFactory : public ConnFactory { 47 | public: 48 | virtual PinkConn* NewPinkConn(int connfd, const std::string& ip_port, 49 | ServerThread* thread, 50 | void* worker_specific_data) const { 51 | return new MyHTTPConn(connfd, ip_port, thread); 52 | } 53 | }; 54 | 55 | static std::atomic running(false); 56 | 57 | static void IntSigHandle(const int sig) { 58 | printf("Catch Signal %d, cleanup...\n", sig); 59 | running.store(false); 60 | printf("server Exit"); 61 | } 62 | 63 | static void SignalSetup() { 64 | signal(SIGHUP, SIG_IGN); 65 | signal(SIGPIPE, SIG_IGN); 66 | signal(SIGINT, &IntSigHandle); 67 | signal(SIGQUIT, &IntSigHandle); 68 | signal(SIGTERM, &IntSigHandle); 69 | } 70 | 71 | int main(int argc, char* argv[]) { 72 | int port; 73 | if (argc < 2) { 74 | printf("Usage: ./simple_http_server port"); 75 | } else { 76 | port = atoi(argv[1]); 77 | } 78 | 79 | SignalSetup(); 80 | 81 | ConnFactory* my_conn_factory = new MyConnFactory(); 82 | ServerThread *st = NewDispatchThread(port, 4, my_conn_factory, 1000); 83 | 84 | if (st->StartThread() != 0) { 85 | printf("StartThread error happened!\n"); 86 | exit(-1); 87 | } 88 | running.store(true); 89 | while (running.load()) { 90 | sleep(1); 91 | } 92 | st->StopThread(); 93 | 94 | delete st; 95 | delete my_conn_factory; 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /pink/include/pink_pubsub.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_PUBSUB_H_ 7 | #define PINK_INCLUDE_PUBSUB_H_ 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "slash/include/xdebug.h" 22 | #include "slash/include/slash_mutex.h" 23 | #include "slash/include/slash_string.h" 24 | 25 | #include "pink/src/pink_epoll.h" 26 | #include "pink/include/pink_thread.h" 27 | #include "pink/include/pink_define.h" 28 | 29 | namespace pink { 30 | 31 | class PinkEpoll; 32 | class PinkFiredEvent; 33 | class PinkConn; 34 | 35 | class PubSubThread : public Thread { 36 | public: 37 | PubSubThread(); 38 | 39 | virtual ~PubSubThread(); 40 | 41 | // PubSub 42 | 43 | int Publish(const std::string& channel, const std::string& msg); 44 | 45 | void Subscribe(PinkConn* conn, 46 | const std::vector& channels, 47 | const bool pattern, 48 | std::vector>* result); 49 | 50 | int UnSubscribe(PinkConn* conn, 51 | const std::vector& channels, 52 | const bool pattern, 53 | std::vector>* result); 54 | 55 | void PubSubChannels(const std::string& pattern, 56 | std::vector* result); 57 | 58 | void PubSubNumSub(const std::vector& channels, 59 | std::vector>* result); 60 | 61 | int PubSubNumPat(); 62 | 63 | private: 64 | void RemoveConn(PinkConn* conn); 65 | 66 | int ClientChannelSize(PinkConn* conn); 67 | 68 | int msg_pfd_[2]; 69 | int notify_pfd_[2]; 70 | bool should_exit_; 71 | 72 | mutable slash::RWMutex rwlock_; /* For external statistics */ 73 | std::map conns_; 74 | 75 | slash::Mutex pub_mutex_; 76 | slash::CondVar receiver_rsignal_; 77 | slash::Mutex receiver_mutex_; 78 | 79 | /* 80 | * receive fd from worker thread 81 | */ 82 | slash::Mutex mutex_; 83 | std::queue fd_queue_; 84 | 85 | std::string channel_; 86 | std::string message_; 87 | int receivers_; 88 | 89 | /* 90 | * The epoll handler 91 | */ 92 | PinkEpoll *pink_epoll_; 93 | 94 | virtual void *ThreadMain(); 95 | 96 | // clean conns 97 | void Cleanup(); 98 | 99 | // PubSub 100 | slash::Mutex channel_mutex_; 101 | slash::Mutex pattern_mutex_; 102 | 103 | std::map> pubsub_channel_; // channel <---> conns 104 | std::map> pubsub_pattern_; // channel <---> conns 105 | 106 | // No copying allowed 107 | PubSubThread(const PubSubThread&); 108 | void operator=(const PubSubThread&); 109 | }; // class PubSubThread 110 | 111 | } // namespace pink 112 | #endif // THIRD_PINK_PINK_INCLUDE_PINK_PUBSUB_H_ 113 | -------------------------------------------------------------------------------- /pink/examples/bg_thread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "unistd.h" 7 | #include 8 | #include 9 | #include "pink/include/bg_thread.h" 10 | #include "slash/include/slash_mutex.h" 11 | 12 | using namespace std; 13 | 14 | static slash::Mutex print_lock; 15 | 16 | void task(void *arg) { 17 | { 18 | slash::MutexLock l(&print_lock); 19 | std::cout << " task : " << *((int *)arg) << std::endl; 20 | } 21 | sleep(1); 22 | delete (int*)arg; 23 | } 24 | 25 | struct TimerItem { 26 | uint64_t exec_time; 27 | void (*function)(void *); 28 | void* arg; 29 | TimerItem(uint64_t _exec_time, void (*_function)(void*), void* _arg) : 30 | exec_time(_exec_time), 31 | function(_function), 32 | arg(_arg) {} 33 | bool operator < (const TimerItem& item) const { 34 | return exec_time > item.exec_time; 35 | } 36 | }; 37 | 38 | int main() { 39 | pink::BGThread t, t2(5); 40 | t.StartThread(); 41 | t2.StartThread(); 42 | int qsize = 0, pqsize = 0; 43 | 44 | std::cout << "Normal BGTask... " << std::endl; 45 | for (int i = 0; i < 10; i++) { 46 | int *pi = new int(i); 47 | t.Schedule(task, (void*)pi); 48 | t.QueueSize(&pqsize, &qsize); 49 | slash::MutexLock l(&print_lock); 50 | std::cout << " current queue size:" << qsize << ", " << pqsize << std::endl; 51 | } 52 | std::cout << std::endl << std::endl; 53 | 54 | while (qsize > 0) { 55 | t.QueueSize(&pqsize, &qsize); 56 | sleep(1); 57 | } 58 | 59 | 60 | qsize = pqsize = 0; 61 | std::cout << "Limit queue BGTask... " << std::endl; 62 | for (int i = 0; i < 10; i++) { 63 | int *pi = new int(i); 64 | t2.Schedule(task, (void*)pi); 65 | t2.QueueSize(&pqsize, &qsize); 66 | slash::MutexLock l(&print_lock); 67 | std::cout << " current queue size:" << qsize << ", " << pqsize << std::endl; 68 | } 69 | std::cout << std::endl << std::endl; 70 | 71 | while (qsize > 0) { 72 | t2.QueueSize(&pqsize, &qsize); 73 | sleep(1); 74 | } 75 | 76 | std::cout << "TimerItem Struct... " << std::endl; 77 | std::priority_queue pq; 78 | pq.push(TimerItem(1, task, NULL)); 79 | pq.push(TimerItem(5, task, NULL)); 80 | pq.push(TimerItem(3, task, NULL)); 81 | pq.push(TimerItem(2, task, NULL)); 82 | pq.push(TimerItem(4, task, NULL)); 83 | 84 | while (!pq.empty()) { 85 | printf("%ld\n", pq.top().exec_time); 86 | pq.pop(); 87 | } 88 | std::cout << std::endl << std::endl; 89 | 90 | std::cout << "Restart BGThread" << std::endl; 91 | t.StopThread(); 92 | t.StartThread(); 93 | std::cout << "Time BGTask... " << std::endl; 94 | for (int i = 0; i < 10; i++) { 95 | int *pi = new int(i); 96 | t.DelaySchedule(i * 1000, task, (void*)pi); 97 | t.QueueSize(&pqsize, &qsize); 98 | slash::MutexLock l(&print_lock); 99 | std::cout << " current queue size:" << qsize << ", " << pqsize << std::endl; 100 | } 101 | sleep(3); 102 | std::cout << "QueueClear..." << std::endl; 103 | t.QueueClear(); 104 | sleep(10); 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /pink/test/gtest/include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // Flag related macros: 34 | // GTEST_FLAG(flag_name) 35 | // GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its 36 | // own flagfile flag parsing. 37 | // GTEST_DECLARE_bool_(name) 38 | // GTEST_DECLARE_int32_(name) 39 | // GTEST_DECLARE_string_(name) 40 | // GTEST_DEFINE_bool_(name, default_val, doc) 41 | // GTEST_DEFINE_int32_(name, default_val, doc) 42 | // GTEST_DEFINE_string_(name, default_val, doc) 43 | // 44 | // Test filtering: 45 | // GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that 46 | // will be used if --GTEST_FLAG(test_filter) 47 | // is not provided. 48 | // 49 | // Logging: 50 | // GTEST_LOG_(severity) 51 | // GTEST_CHECK_(condition) 52 | // Functions LogToStderr() and FlushInfoLog() have to be provided too. 53 | // 54 | // Threading: 55 | // GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided. 56 | // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are 57 | // already provided. 58 | // Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and 59 | // GTEST_DEFINE_STATIC_MUTEX_(mutex) 60 | // 61 | // GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) 62 | // GTEST_LOCK_EXCLUDED_(locks) 63 | // 64 | // ** Custom implementation starts here ** 65 | 66 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 67 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 68 | 69 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 70 | -------------------------------------------------------------------------------- /pink/examples/myredis_srv.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pink/include/server_thread.h" 8 | #include "pink/include/pink_conn.h" 9 | #include "pink/include/redis_conn.h" 10 | #include "pink/include/pink_thread.h" 11 | 12 | using namespace pink; 13 | 14 | std::map db; 15 | 16 | 17 | class MyConn: public RedisConn { 18 | public: 19 | MyConn(int fd, const std::string& ip_port, ServerThread *thread, 20 | void* worker_specific_data); 21 | virtual ~MyConn() = default; 22 | 23 | protected: 24 | int DealMessage(RedisCmdArgsType& argv, std::string* response) override; 25 | 26 | private: 27 | }; 28 | 29 | MyConn::MyConn(int fd, const std::string& ip_port, 30 | ServerThread *thread, void* worker_specific_data) 31 | : RedisConn(fd, ip_port, thread) { 32 | // Handle worker_specific_data ... 33 | } 34 | 35 | int MyConn::DealMessage(RedisCmdArgsType& argv, std::string* response) { 36 | printf("Get redis message "); 37 | for (int i = 0; i < argv.size(); i++) { 38 | printf("%s ", argv[i].c_str()); 39 | } 40 | printf("\n"); 41 | 42 | std::string val = "result"; 43 | std::string res; 44 | // set command 45 | if (argv.size() == 3) { 46 | response->append("+OK\r\n"); 47 | db[argv[1]] = argv[2]; 48 | } else if (argv.size() == 2) { 49 | std::map::iterator iter = db.find(argv[1]); 50 | if (iter != db.end()) { 51 | const std::string& val = iter->second; 52 | response->append("*1\r\n$"); 53 | response->append(std::to_string(val.length())); 54 | response->append("\r\n"); 55 | response->append(val); 56 | response->append("\r\n"); 57 | } else { 58 | response->append("$-1\r\n"); 59 | } 60 | } else { 61 | response->append("+OK\r\n"); 62 | } 63 | return 0; 64 | } 65 | 66 | class MyConnFactory : public ConnFactory { 67 | public: 68 | virtual PinkConn *NewPinkConn(int connfd, const std::string &ip_port, 69 | ServerThread *thread, 70 | void* worker_specific_data) const { 71 | return new MyConn(connfd, ip_port, thread, worker_specific_data); 72 | } 73 | }; 74 | 75 | static std::atomic running(false); 76 | 77 | static void IntSigHandle(const int sig) { 78 | printf("Catch Signal %d, cleanup...\n", sig); 79 | running.store(false); 80 | printf("server Exit"); 81 | } 82 | 83 | static void SignalSetup() { 84 | signal(SIGHUP, SIG_IGN); 85 | signal(SIGPIPE, SIG_IGN); 86 | signal(SIGINT, &IntSigHandle); 87 | signal(SIGQUIT, &IntSigHandle); 88 | signal(SIGTERM, &IntSigHandle); 89 | } 90 | 91 | int main(int argc, char* argv[]) { 92 | if (argc < 2) { 93 | printf("server will listen to 6379\n"); 94 | } else { 95 | printf("server will listen to %d\n", atoi(argv[1])); 96 | } 97 | int my_port = (argc > 1) ? atoi(argv[1]) : 6379; 98 | 99 | SignalSetup(); 100 | 101 | ConnFactory *conn_factory = new MyConnFactory(); 102 | 103 | ServerThread* my_thread = NewHolyThread(my_port, conn_factory, 1000); 104 | if (my_thread->StartThread() != 0) { 105 | printf("StartThread error happened!\n"); 106 | exit(-1); 107 | } 108 | running.store(true); 109 | while (running.load()) { 110 | sleep(1); 111 | } 112 | my_thread->StopThread(); 113 | 114 | delete my_thread; 115 | delete conn_factory; 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /pink/examples/http_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "slash/include/slash_status.h" 12 | #include "slash/include/slash_hash.h" 13 | #include "pink/include/pink_thread.h" 14 | #include "pink/include/server_thread.h" 15 | #include "pink/include/http_conn.h" 16 | 17 | using namespace pink; 18 | 19 | class MyHTTPHandles : public pink::HTTPHandles { 20 | public: 21 | std::string body_data; 22 | std::string body_md5; 23 | std::string zero_space; 24 | size_t write_pos = 0; 25 | std::chrono::system_clock::time_point start, end; 26 | std::chrono::duration diff; 27 | 28 | // Request handles 29 | virtual bool HandleRequest(const HTTPRequest* req) { 30 | req->Dump(); 31 | body_data.clear(); 32 | 33 | start = std::chrono::system_clock::now(); 34 | 35 | // Continue receive body 36 | return false; 37 | } 38 | virtual void HandleBodyData(const char* data, size_t size) { 39 | std::cout << "ReqBodyPartHandle: " << size << std::endl; 40 | body_data.append(data, size); 41 | } 42 | 43 | // Response handles 44 | virtual void PrepareResponse(HTTPResponse* resp) { 45 | body_md5.assign(slash::md5(body_data)); 46 | 47 | resp->SetStatusCode(200); 48 | resp->SetContentLength(body_md5.size()); 49 | write_pos = 0; 50 | end = std::chrono::system_clock::now(); 51 | diff = end - start; 52 | std::cout << "Use: " << diff.count() << " ms" << std::endl; 53 | } 54 | 55 | virtual int WriteResponseBody(char* buf, size_t max_size) { 56 | size_t size = std::min(max_size, body_md5.size() - write_pos); 57 | memcpy(buf, body_md5.data() + write_pos, size); 58 | write_pos += size; 59 | return size; 60 | } 61 | }; 62 | 63 | class MyConnFactory : public ConnFactory { 64 | public: 65 | virtual PinkConn* NewPinkConn(int connfd, const std::string& ip_port, 66 | ServerThread* thread, 67 | void* worker_specific_data) const { 68 | auto my_handles = std::make_shared(); 69 | return new pink::HTTPConn(connfd, ip_port, thread, my_handles, 70 | worker_specific_data); 71 | } 72 | }; 73 | 74 | static std::atomic running(false); 75 | 76 | static void IntSigHandle(const int sig) { 77 | printf("Catch Signal %d, cleanup...\n", sig); 78 | running.store(false); 79 | printf("server Exit"); 80 | } 81 | 82 | static void SignalSetup() { 83 | signal(SIGHUP, SIG_IGN); 84 | signal(SIGPIPE, SIG_IGN); 85 | signal(SIGINT, &IntSigHandle); 86 | signal(SIGQUIT, &IntSigHandle); 87 | signal(SIGTERM, &IntSigHandle); 88 | } 89 | 90 | int main(int argc, char* argv[]) { 91 | int port; 92 | if (argc < 2) { 93 | printf("Usage: ./http_server port"); 94 | } else { 95 | port = atoi(argv[1]); 96 | } 97 | 98 | SignalSetup(); 99 | 100 | ConnFactory* my_conn_factory = new MyConnFactory(); 101 | ServerThread *st = NewDispatchThread(port, 4, my_conn_factory, 1000); 102 | 103 | if (st->StartThread() != 0) { 104 | printf("StartThread error happened!\n"); 105 | exit(-1); 106 | } 107 | running.store(true); 108 | while (running.load()) { 109 | sleep(1); 110 | } 111 | st->StopThread(); 112 | 113 | delete st; 114 | delete my_conn_factory; 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Pink 2 | 3 | [![Build Status](https://travis-ci.org/PikaLabs/pink.svg?branch=master)](https://travis-ci.org/PikaLabs/pink) 4 | 5 | Pink is a wrapper of pthread. Why you need it? 6 | 7 | When you use pthread, you always define many type of thread, such as: 8 | 9 | In network programming scenario, some thread used for accept the client's connection, some thread used for pass 10 | message to other thread, some thread used for communicate with client using protobuf. 11 | 12 | So pink wrap a thin capsulation upon pthread to offer more convinent function. 13 | 14 | ### Model 15 | 16 | DispatchThread + Multi WorkerThread 17 | 18 | ![](http://i.imgur.com/XXfibpV.png) 19 | 20 | Now pink support these type of thread: 21 | 22 | #### DispatchThread: 23 | 24 | DispatchThread is used for listen a port, and get an accept connection. And then 25 | dispatch this connection to the worker thread, you can use different protocol, 26 | now we have support google protobuf protocol. And you just need write the 27 | protocol, and then generate the code. The worker threads will deal with the 28 | protocol analysis, so it simplify your job. 29 | 30 | Basic usage example: 31 | 32 | ``` 33 | PikaConnFactory conn_factory; 34 | PikaServerHandle server_handle; 35 | ServerThread *t = new NewDispatchThread(9211, /* server port */ 36 | 4, /* worker's number */ 37 | &conn_factory, 38 | 1000, /* cron interval */ 39 | 1000, /* queue limit */ 40 | &server_handle); 41 | t->StartThread(); 42 | 43 | ``` 44 | 45 | You can see example/mydispatch_srv.cc for more detail 46 | 47 | 48 | #### HolyThread: 49 | 50 | HolyThread just like the redis's main thread, it is the thread that both listen a port and do 51 | the job. When should you use HolyThread and When should you use DispatchThread 52 | combine with WorkerThread, if your job is not so busy, so you can use HolyThread 53 | do the all job. if your job is deal lots of client's request, we suggest you use 54 | DispathThread with worker threads. 55 | 56 | Basic usage example: 57 | 58 | ``` 59 | PikaConnFactory conn_factory; 60 | PikaServerHandle server_handle; 61 | ServerThread *t = new NewHolyThread(9211, /* server port */ 62 | &conn_factory, 63 | 1000, /* cron interval */ 64 | &server_handle); 65 | t->StartThread(); 66 | 67 | ``` 68 | 69 | You can see example/myholy_srv_chandle.cc example/myholy_srv.cc for more detail 70 | 71 | Now we will use pink build our project [pika](https://github.com/Qihoo360/pika), [floyd](https://github.com/PikaLabs/floyd), [zeppelin](https://github.com/Qihoo360/zeppelin) 72 | 73 | In the future, I will add some thread manager in pink. 74 | 75 | ### Dependencies 76 | 77 | - [slash v1.0+](https://github.com/PikaLabs/slash) 78 | 79 | - [protobuf v2.5.0](https://github.com/google/protobuf/releases/tag/v2.5.0) 80 | 81 | - OpenSSL if enable ssl 82 | 83 | ### Performance 84 | 85 | Test machines: 86 | 87 | ``` 88 | -------- -------------- 89 | | | <--- | Clients x200 | 90 | | Server | -------------- 91 | | | -------------- 92 | -------- <--- | Clients x200 | 93 | -------------- 94 | ``` 95 | 96 | CPU, Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz, 24 cores 97 | 98 | Memory, 142 GB 99 | 100 | [test 101 | program](https://github.com/PikaLabs/pink/tree/master/pink/example/performance) 102 | 103 | ![](https://ws4.sinaimg.cn/large/006tKfTcly1fho384upsjj30f00a5gm8.jpg) 104 | -------------------------------------------------------------------------------- /pink/include/simple_http_conn.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_SIMPLE_HTTP_CONN_H_ 7 | #define PINK_INCLUDE_SIMPLE_HTTP_CONN_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "slash/include/slash_status.h" 14 | #include "slash/include/xdebug.h" 15 | 16 | #include "pink/include/pink_conn.h" 17 | #include "pink/include/pink_define.h" 18 | #include "pink/src/pink_util.h" 19 | 20 | namespace pink { 21 | 22 | class Request { 23 | public: 24 | // attach in header 25 | std::string method; 26 | std::string path; 27 | std::string version; 28 | std::map headers; 29 | 30 | // in header for Get, in content for Post Put Delete 31 | std::map query_params; 32 | 33 | // POST: content-type: application/x-www-form-urlencoded 34 | std::map post_params; 35 | 36 | // attach in content 37 | std::string content; 38 | 39 | Request(); 40 | void Clear(); 41 | bool ParseHeadFromArray(const char* data, const int size); 42 | bool ParseBodyFromArray(const char* data, const int size); 43 | 44 | private: 45 | enum ParseStatus { 46 | kHeaderMethod, 47 | kHeaderPath, 48 | kHeaderVersion, 49 | kHeaderParamKey, 50 | kHeaderParamValue, 51 | kBody 52 | }; 53 | 54 | bool ParseGetUrl(); 55 | bool ParseHeadLine( 56 | const char* data, int line_start, 57 | int line_end, ParseStatus* parseStatus); 58 | bool ParseParameters( 59 | const std::string data, 60 | size_t line_start = 0, 61 | bool from_url = true); 62 | }; 63 | 64 | class Response { 65 | public: 66 | Response(): 67 | status_code_(0) { 68 | } 69 | void Clear(); 70 | int SerializeHeaderToArray(char* data, size_t size); 71 | int SerializeBodyToArray(char* data, size_t size, int *pos); 72 | bool HasMoreBody(size_t pos) { 73 | return pos < body_.size(); 74 | } 75 | 76 | void SetStatusCode(int code); 77 | 78 | void SetHeaders(const std::string &key, const std::string &value) { 79 | headers_[key] = value; 80 | } 81 | 82 | void SetHeaders(const std::string &key, const int value) { 83 | headers_[key] = std::to_string(value); 84 | } 85 | 86 | void SetBody(const std::string &body) { 87 | body_.assign(body); 88 | } 89 | 90 | private: 91 | int status_code_; 92 | std::string reason_phrase_; 93 | std::map headers_; 94 | std::string body_; 95 | }; 96 | 97 | class SimpleHTTPConn: public PinkConn { 98 | public: 99 | SimpleHTTPConn( 100 | const int fd, 101 | const std::string &ip_port, 102 | ServerThread *thread); 103 | virtual ~SimpleHTTPConn(); 104 | 105 | virtual ReadStatus GetRequest() override; 106 | virtual WriteStatus SendReply() override; 107 | 108 | private: 109 | virtual void DealMessage(const Request* req, Response* res) = 0; 110 | 111 | bool BuildRequestHeader(); 112 | bool AppendRequestBody(); 113 | bool FillResponseBuf(); 114 | void HandleMessage(); 115 | 116 | ConnStatus conn_status_; 117 | char* rbuf_; 118 | uint32_t rbuf_pos_; 119 | char* wbuf_; 120 | uint32_t wbuf_len_; // length we wanna write out 121 | uint32_t wbuf_pos_; 122 | uint32_t header_len_; 123 | uint64_t remain_packet_len_; 124 | 125 | Request* request_; 126 | int response_pos_; 127 | Response* response_; 128 | }; 129 | 130 | } // namespace pink 131 | #endif // PINK_INCLUDE_SIMPLE_HTTP_CONN_H_ 132 | -------------------------------------------------------------------------------- /pink/test/gtest/include/gtest/internal/gtest-port-arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing Framework (Google Test) 31 | // 32 | // This header file defines the GTEST_OS_* macro. 33 | // It is separate from gtest-port.h so that custom/gtest-port.h can include it. 34 | 35 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 36 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 37 | 38 | // Determines the platform on which Google Test is compiled. 39 | #ifdef __CYGWIN__ 40 | # define GTEST_OS_CYGWIN 1 41 | #elif defined __SYMBIAN32__ 42 | # define GTEST_OS_SYMBIAN 1 43 | #elif defined _WIN32 44 | # define GTEST_OS_WINDOWS 1 45 | # ifdef _WIN32_WCE 46 | # define GTEST_OS_WINDOWS_MOBILE 1 47 | # elif defined(__MINGW__) || defined(__MINGW32__) 48 | # define GTEST_OS_WINDOWS_MINGW 1 49 | # elif defined(WINAPI_FAMILY) 50 | # include 51 | # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 52 | # define GTEST_OS_WINDOWS_DESKTOP 1 53 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) 54 | # define GTEST_OS_WINDOWS_PHONE 1 55 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 56 | # define GTEST_OS_WINDOWS_RT 1 57 | # else 58 | // WINAPI_FAMILY defined but no known partition matched. 59 | // Default to desktop. 60 | # define GTEST_OS_WINDOWS_DESKTOP 1 61 | # endif 62 | # else 63 | # define GTEST_OS_WINDOWS_DESKTOP 1 64 | # endif // _WIN32_WCE 65 | #elif defined __APPLE__ 66 | # define GTEST_OS_MAC 1 67 | # if TARGET_OS_IPHONE 68 | # define GTEST_OS_IOS 1 69 | # endif 70 | #elif defined __FreeBSD__ 71 | # define GTEST_OS_FREEBSD 1 72 | #elif defined __linux__ 73 | # define GTEST_OS_LINUX 1 74 | # if defined __ANDROID__ 75 | # define GTEST_OS_LINUX_ANDROID 1 76 | # endif 77 | #elif defined __MVS__ 78 | # define GTEST_OS_ZOS 1 79 | #elif defined(__sun) && defined(__SVR4) 80 | # define GTEST_OS_SOLARIS 1 81 | #elif defined(_AIX) 82 | # define GTEST_OS_AIX 1 83 | #elif defined(__hpux) 84 | # define GTEST_OS_HPUX 1 85 | #elif defined __native_client__ 86 | # define GTEST_OS_NACL 1 87 | #elif defined __OpenBSD__ 88 | # define GTEST_OS_OPENBSD 1 89 | #elif defined __QNX__ 90 | # define GTEST_OS_QNX 1 91 | #endif // __CYGWIN__ 92 | 93 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 94 | -------------------------------------------------------------------------------- /pink/examples/myholy_srv_chandle.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pink/include/server_thread.h" 7 | #include "pink/include/pink_conn.h" 8 | #include "pink/include/pb_conn.h" 9 | #include "pink/include/pink_thread.h" 10 | #include "myproto.pb.h" 11 | 12 | using namespace pink; 13 | 14 | class MyConn: public PbConn { 15 | public: 16 | MyConn(int fd, std::string ip_port, ServerThread *thread, void* private_data); 17 | virtual ~MyConn(); 18 | 19 | ServerThread* thread() { 20 | return thread_; 21 | } 22 | 23 | protected: 24 | virtual int DealMessage(); 25 | 26 | private: 27 | ServerThread *thread_; 28 | int* private_data_; 29 | myproto::Ping ping_; 30 | myproto::PingRes ping_res_; 31 | }; 32 | 33 | MyConn::MyConn(int fd, ::std::string ip_port, ServerThread *thread, 34 | void* worker_specific_data) 35 | : PbConn(fd, ip_port, thread), 36 | thread_(thread), 37 | private_data_(static_cast(worker_specific_data)) { 38 | } 39 | 40 | MyConn::~MyConn() { 41 | } 42 | 43 | int MyConn::DealMessage() { 44 | printf("In the myconn DealMessage branch\n"); 45 | ping_.ParseFromArray(rbuf_ + cur_pos_ - header_len_, header_len_); 46 | printf ("DealMessage receive (%s) port %d \n", ping_.address().c_str(), ping_.port()); 47 | 48 | int* data = static_cast(private_data_); 49 | printf("Worker's Env: %d\n", *data); 50 | 51 | ping_res_.Clear(); 52 | ping_res_.set_res(11234); 53 | ping_res_.set_mess("heiheidfdfdf"); 54 | res_ = &ping_res_; 55 | set_is_reply(true); 56 | return 0; 57 | } 58 | 59 | class MyConnFactory : public ConnFactory { 60 | public: 61 | virtual PinkConn *NewPinkConn(int connfd, const std::string &ip_port, 62 | ServerThread *thread, 63 | void* worker_specific_data) const { 64 | return new MyConn(connfd, ip_port, thread, worker_specific_data); 65 | } 66 | }; 67 | 68 | class MyServerHandle : public ServerHandle { 69 | public: 70 | virtual void CronHandle() const override { 71 | printf ("Cron operation\n"); 72 | } 73 | using ServerHandle::AccessHandle; 74 | virtual bool AccessHandle(std::string& ip) const override { 75 | printf ("Access operation, receive:%s\n", ip.c_str()); 76 | return true; 77 | } 78 | virtual int CreateWorkerSpecificData(void** data) const { 79 | int *num = new int(1234); 80 | *data = static_cast(num); 81 | return 0; 82 | } 83 | virtual int DeleteWorkerSpecificData(void* data) const { 84 | delete static_cast(data); 85 | return 0; 86 | } 87 | }; 88 | 89 | static std::atomic running(false); 90 | 91 | static void IntSigHandle(const int sig) { 92 | printf("Catch Signal %d, cleanup...\n", sig); 93 | running.store(false); 94 | printf("server Exit"); 95 | } 96 | 97 | static void SignalSetup() { 98 | signal(SIGHUP, SIG_IGN); 99 | signal(SIGPIPE, SIG_IGN); 100 | signal(SIGINT, &IntSigHandle); 101 | signal(SIGQUIT, &IntSigHandle); 102 | signal(SIGTERM, &IntSigHandle); 103 | } 104 | 105 | int main(int argc, char* argv[]) { 106 | if (argc < 2) { 107 | printf ("Usage: ./server port\n"); 108 | exit(0); 109 | } 110 | 111 | int my_port = (argc > 1) ? atoi(argv[1]) : 8221; 112 | 113 | SignalSetup(); 114 | 115 | MyConnFactory conn_factory; 116 | MyServerHandle handle; 117 | 118 | ServerThread* my_thread = NewHolyThread(my_port, &conn_factory, 1000, &handle); 119 | if (my_thread->StartThread() != 0) { 120 | printf("StartThread error happened!\n"); 121 | exit(-1); 122 | } 123 | running.store(true); 124 | while (running.load()) { 125 | sleep(1); 126 | } 127 | my_thread->StopThread(); 128 | 129 | delete my_thread; 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /pink/examples/https_server.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "slash/include/slash_status.h" 12 | #include "slash/include/slash_hash.h" 13 | #include "pink/include/pink_thread.h" 14 | #include "pink/include/server_thread.h" 15 | #include "pink/include/http_conn.h" 16 | 17 | using namespace pink; 18 | 19 | class MyHTTPHandles : public pink::HTTPHandles { 20 | public: 21 | std::string body_data; 22 | std::string body_md5; 23 | std::string zero_space; 24 | size_t write_pos = 0; 25 | std::chrono::system_clock::time_point start, end; 26 | std::chrono::duration diff; 27 | 28 | // Request handles 29 | virtual bool HandleRequest(const HTTPRequest* req) { 30 | req->Dump(); 31 | body_data.clear(); 32 | 33 | start = std::chrono::system_clock::now(); 34 | 35 | // Continue receive body 36 | return false; 37 | } 38 | virtual void HandleBodyData(const char* data, size_t size) { 39 | std::cout << "ReqBodyPartHandle: " << size << std::endl; 40 | body_data.append(data, size); 41 | } 42 | 43 | // Response handles 44 | virtual void PrepareResponse(HTTPResponse* resp) { 45 | body_md5.assign(slash::md5(body_data)); 46 | 47 | resp->SetStatusCode(200); 48 | resp->SetContentLength(body_md5.size()); 49 | write_pos = 0; 50 | end = std::chrono::system_clock::now(); 51 | diff = end - start; 52 | std::cout << "Use: " << diff.count() << " ms" << std::endl; 53 | } 54 | 55 | virtual int WriteResponseBody(char* buf, size_t max_size) { 56 | size_t size = std::min(max_size, body_md5.size() - write_pos); 57 | memcpy(buf, body_md5.data() + write_pos, size); 58 | write_pos += size; 59 | return size; 60 | } 61 | }; 62 | 63 | class MyConnFactory : public ConnFactory { 64 | public: 65 | virtual PinkConn* NewPinkConn(int connfd, const std::string& ip_port, 66 | ServerThread* thread, 67 | void* worker_specific_data) const { 68 | auto my_handles = std::make_shared(); 69 | return new pink::HTTPConn(connfd, ip_port, thread, my_handles, 70 | worker_specific_data); 71 | } 72 | }; 73 | 74 | static std::atomic running(false); 75 | 76 | static void IntSigHandle(const int sig) { 77 | printf("Catch Signal %d, cleanup...\n", sig); 78 | running.store(false); 79 | printf("server Exit"); 80 | } 81 | 82 | static void SignalSetup() { 83 | signal(SIGHUP, SIG_IGN); 84 | signal(SIGPIPE, SIG_IGN); 85 | signal(SIGINT, &IntSigHandle); 86 | signal(SIGQUIT, &IntSigHandle); 87 | signal(SIGTERM, &IntSigHandle); 88 | } 89 | 90 | int main(int argc, char* argv[]) { 91 | int port; 92 | if (argc < 2) { 93 | printf("Usage: ./http_server port"); 94 | } else { 95 | port = atoi(argv[1]); 96 | } 97 | 98 | SignalSetup(); 99 | 100 | ConnFactory* my_conn_factory = new MyConnFactory(); 101 | ServerThread *st = NewDispatchThread(port, 4, my_conn_factory, 1000); 102 | 103 | if (st->EnableSecurity("/complete_path_to/host.crt", 104 | "/complete_path_to/host.key") != 0) { 105 | printf("EnableSecurity error happened!\n"); 106 | exit(-1); 107 | } 108 | 109 | if (st->StartThread() != 0) { 110 | printf("StartThread error happened!\n"); 111 | exit(-1); 112 | } 113 | running.store(true); 114 | while (running.load()) { 115 | sleep(1); 116 | } 117 | st->StopThread(); 118 | 119 | delete st; 120 | delete my_conn_factory; 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/gmock.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This is the main header file a user should include. 35 | 36 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ 37 | #define GMOCK_INCLUDE_GMOCK_GMOCK_H_ 38 | 39 | // This file implements the following syntax: 40 | // 41 | // ON_CALL(mock_object.Method(...)) 42 | // .With(...) ? 43 | // .WillByDefault(...); 44 | // 45 | // where With() is optional and WillByDefault() must appear exactly 46 | // once. 47 | // 48 | // EXPECT_CALL(mock_object.Method(...)) 49 | // .With(...) ? 50 | // .Times(...) ? 51 | // .InSequence(...) * 52 | // .WillOnce(...) * 53 | // .WillRepeatedly(...) ? 54 | // .RetiresOnSaturation() ? ; 55 | // 56 | // where all clauses are optional and WillOnce() can be repeated. 57 | 58 | #include "gmock/gmock-actions.h" 59 | #include "gmock/gmock-cardinalities.h" 60 | #include "gmock/gmock-generated-actions.h" 61 | #include "gmock/gmock-generated-function-mockers.h" 62 | #include "gmock/gmock-generated-nice-strict.h" 63 | #include "gmock/gmock-generated-matchers.h" 64 | #include "gmock/gmock-matchers.h" 65 | #include "gmock/gmock-more-actions.h" 66 | #include "gmock/gmock-more-matchers.h" 67 | #include "gmock/internal/gmock-internal-utils.h" 68 | 69 | namespace testing { 70 | 71 | // Declares Google Mock flags that we want a user to use programmatically. 72 | GMOCK_DECLARE_bool_(catch_leaked_mocks); 73 | GMOCK_DECLARE_string_(verbose); 74 | 75 | // Initializes Google Mock. This must be called before running the 76 | // tests. In particular, it parses the command line for the flags 77 | // that Google Mock recognizes. Whenever a Google Mock flag is seen, 78 | // it is removed from argv, and *argc is decremented. 79 | // 80 | // No value is returned. Instead, the Google Mock flag variables are 81 | // updated. 82 | // 83 | // Since Google Test is needed for Google Mock to work, this function 84 | // also initializes Google Test and parses its flags, if that hasn't 85 | // been done. 86 | GTEST_API_ void InitGoogleMock(int* argc, char** argv); 87 | 88 | // This overloaded version can be used in Windows programs compiled in 89 | // UNICODE mode. 90 | GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); 91 | 92 | } // namespace testing 93 | 94 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_ 95 | -------------------------------------------------------------------------------- /pink/src/bg_thread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "pink/include/bg_thread.h" 7 | #include 8 | 9 | #include "slash/include/slash_mutex.h" 10 | #include "slash/include/xdebug.h" 11 | 12 | namespace pink { 13 | 14 | void BGThread::Schedule(void (*function)(void*), void* arg) { 15 | mu_.Lock(); 16 | while (queue_.size() >= full_ && !should_stop()) { 17 | wsignal_.Wait(); 18 | } 19 | if (!should_stop()) { 20 | queue_.push(BGItem(function, arg)); 21 | rsignal_.Signal(); 22 | } 23 | mu_.Unlock(); 24 | } 25 | 26 | void BGThread::QueueSize(int* pri_size, int* qu_size) { 27 | slash::MutexLock l(&mu_); 28 | *pri_size = timer_queue_.size(); 29 | *qu_size = queue_.size(); 30 | } 31 | 32 | void BGThread::QueueClear() { 33 | slash::MutexLock l(&mu_); 34 | std::queue().swap(queue_); 35 | std::priority_queue().swap(timer_queue_); 36 | } 37 | 38 | void BGThread::SwallowReadyTasks() { 39 | // it's safe to swallow all the remain tasks in ready and timer queue, 40 | // while the schedule function would stop to add any tasks. 41 | mu_.Lock(); 42 | while (!queue_.empty()) { 43 | void (*function)(void*) = queue_.front().function; 44 | void* arg = queue_.front().arg; 45 | queue_.pop(); 46 | mu_.Unlock(); 47 | (*function)(arg); 48 | mu_.Lock(); 49 | } 50 | mu_.Unlock(); 51 | 52 | struct timeval now; 53 | gettimeofday(&now, NULL); 54 | uint64_t unow = now.tv_sec * 1000000 + now.tv_usec; 55 | mu_.Lock(); 56 | while(!timer_queue_.empty()) { 57 | TimerItem top_item = timer_queue_.top(); 58 | if (unow / 1000 < top_item.exec_time / 1000) { 59 | break; 60 | } 61 | void (*function)(void*) = top_item.function; 62 | void* arg = top_item.arg; 63 | timer_queue_.pop(); 64 | // Don't lock while doing task 65 | mu_.Unlock(); 66 | (*function)(arg); 67 | mu_.Lock(); 68 | } 69 | mu_.Unlock(); 70 | } 71 | 72 | void *BGThread::ThreadMain() { 73 | while (!should_stop()) { 74 | mu_.Lock(); 75 | while (queue_.empty() && timer_queue_.empty() && !should_stop()) { 76 | rsignal_.Wait(); 77 | } 78 | if (should_stop()) { 79 | mu_.Unlock(); 80 | break; 81 | } 82 | if (!timer_queue_.empty()) { 83 | struct timeval now; 84 | gettimeofday(&now, NULL); 85 | 86 | TimerItem timer_item = timer_queue_.top(); 87 | uint64_t unow = now.tv_sec * 1000000 + now.tv_usec; 88 | if (unow / 1000 >= timer_item.exec_time / 1000) { 89 | void (*function)(void*) = timer_item.function; 90 | void* arg = timer_item.arg; 91 | timer_queue_.pop(); 92 | mu_.Unlock(); 93 | (*function)(arg); 94 | continue; 95 | } else if (queue_.empty() && !should_stop()) { 96 | rsignal_.TimedWait( 97 | static_cast((timer_item.exec_time - unow) / 1000)); 98 | mu_.Unlock(); 99 | continue; 100 | } 101 | } 102 | if (!queue_.empty()) { 103 | void (*function)(void*) = queue_.front().function; 104 | void* arg = queue_.front().arg; 105 | queue_.pop(); 106 | wsignal_.Signal(); 107 | mu_.Unlock(); 108 | (*function)(arg); 109 | } 110 | } 111 | // swalloc all the remain tasks in ready and timer queue 112 | SwallowReadyTasks(); 113 | return NULL; 114 | } 115 | 116 | /* 117 | * timeout is in millisecond 118 | */ 119 | void BGThread::DelaySchedule( 120 | uint64_t timeout, void (*function)(void *), void* arg) { 121 | /* 122 | * pthread_cond_timedwait api use absolute API 123 | * so we need gettimeofday + timeout 124 | */ 125 | struct timeval now; 126 | gettimeofday(&now, NULL); 127 | uint64_t exec_time; 128 | exec_time = now.tv_sec * 1000000 + timeout * 1000 + now.tv_usec; 129 | 130 | mu_.Lock(); 131 | if (!should_stop()) { 132 | timer_queue_.push(TimerItem(exec_time, function, arg)); 133 | rsignal_.Signal(); 134 | } 135 | mu_.Unlock(); 136 | } 137 | 138 | } // namespace pink 139 | -------------------------------------------------------------------------------- /pink/examples/redis_cli_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "slash/include/xdebug.h" 4 | #include "pink/include/pink_cli.h" 5 | #include "pink/include/redis_cli.h" 6 | 7 | using namespace pink; 8 | 9 | int main(int argc, char* argv[]) { 10 | if (argc < 3) { 11 | printf ("Usage: ./redis_cli ip port\n"); 12 | exit(0); 13 | } 14 | 15 | std::string ip(argv[1]); 16 | int port = atoi(argv[2]); 17 | 18 | std::string str; 19 | int i = 5; 20 | 21 | printf ("\nTest Serialize\n"); 22 | int ret = pink::SerializeRedisCommand(&str, "HSET %s %d", "key", i); 23 | printf (" 1. Serialize by va return %d, (%s)\n", ret, str.c_str()); 24 | 25 | RedisCmdArgsType vec; 26 | vec.push_back("hset"); 27 | vec.push_back("key"); 28 | vec.push_back(std::to_string(5)); 29 | 30 | ret = pink::SerializeRedisCommand(vec, &str); 31 | printf (" 2. Serialize by vec return %d, (%s)\n", ret, str.c_str()); 32 | 33 | PinkCli *rcli = NewRedisCli(); 34 | rcli->set_connect_timeout(3000); 35 | 36 | // redis v3.2+ protect mode will block other ip 37 | //printf (" Connect with bind_ip(101.199.114.205)\n"); 38 | //Status s = rcli->Connect(ip, port, "101.199.114.205"); 39 | 40 | Status s = rcli->Connect(ip, port, "101.199.114.205"); 41 | // Test connect timeout with a non-routable IP 42 | //Status s = rcli->Connect("10.255.255.1", 9824); 43 | 44 | printf(" RedisCli Connect(%s:%d) return %s\n", ip.c_str(), port, s.ToString().c_str()); 45 | if (!s.ok()) { 46 | printf ("Connect failed, %s\n", s.ToString().c_str()); 47 | exit(-1); 48 | } 49 | 50 | ret = rcli->set_send_timeout(100); 51 | printf("set send timeout 100 ms, return %d\n", ret); 52 | 53 | ret = rcli->set_recv_timeout(100); 54 | printf("set recv timeout 100 ms, return %d\n", ret); 55 | 56 | /* 57 | char ch; 58 | scanf ("%c", &ch); 59 | */ 60 | 61 | pink::RedisCmdArgsType redis_argv; 62 | printf ("\nTest Send and Recv Ping\n"); 63 | std::string ping = "*1\r\n$4\r\nping\r\n"; 64 | for (int i = 0; i < 1; i++) { 65 | s = rcli->Send(&ping); 66 | printf("Send %d: %s\n", i, s.ToString().c_str()); 67 | 68 | s = rcli->Recv(&redis_argv); 69 | printf("Recv %d: return %s\n", i, s.ToString().c_str()); 70 | if (redis_argv.size() > 0) { 71 | printf(" redis_argv[0] is (%s)\n", redis_argv[0].c_str()); 72 | } 73 | } 74 | 75 | printf ("\nTest Send and Recv Mutli\n"); 76 | pink::SerializeRedisCommand(&str, "MSET a 1 b 2 c 3 d 4"); 77 | printf ("Send mset parse (%s)\n", str.c_str()); 78 | s = rcli->Send(&str); 79 | printf ("Send mset return %s\n", s.ToString().c_str()); 80 | 81 | s = rcli->Recv(&redis_argv); 82 | printf("Recv mset return %s with %lu elements\n", s.ToString().c_str(), redis_argv.size()); 83 | for (size_t i = 0; i < redis_argv.size(); i++) { 84 | printf(" redis_argv[%lu] = (%s)", i, redis_argv[i].c_str()); 85 | } 86 | 87 | printf ("\n\nTest Mget case 1: send 1 time, and recv 1 time\n"); 88 | pink::SerializeRedisCommand(&str, "MGET a b c d "); 89 | printf ("Send mget parse (%s)\n", str.c_str()); 90 | 91 | for (int si = 0; si < 2; si++) { 92 | s = rcli->Send(&str); 93 | printf ("Send mget case 1: i=%d, return %s\n", si, s.ToString().c_str()); 94 | 95 | s = rcli->Recv(&redis_argv); 96 | printf ("Recv mget case 1: i=%d, return %s with %lu elements\n", si, s.ToString().c_str(), redis_argv.size()); 97 | for (size_t i = 0; i < redis_argv.size(); i++) { 98 | printf(" redis_argv[%lu] = (%s)\n", i, redis_argv[i].c_str()); 99 | } 100 | } 101 | 102 | printf ("\nTest Mget case 2: send 2 times, then recv 2 times\n"); 103 | pink::SerializeRedisCommand(&str, "MGET a b c d "); 104 | printf ("\nSend mget parse (%s)\n", str.c_str()); 105 | 106 | for (int si = 0; si < 2; si++) { 107 | s = rcli->Send(&str); 108 | printf ("Send mget case 2: i=%d, return %s\n", si, s.ToString().c_str()); 109 | } 110 | 111 | for (int si = 0; si < 2; si++) { 112 | s = rcli->Recv(&redis_argv); 113 | printf ("Recv mget case 1: i=%d, return %s with %lu elements\n", si, s.ToString().c_str(), redis_argv.size()); 114 | for (size_t i = 0; i < redis_argv.size(); i++) { 115 | printf (" redis_argv[%lu] = (%s)\n", i, redis_argv[i].c_str()); 116 | } 117 | } 118 | 119 | char ch; 120 | scanf ("%c", &ch); 121 | 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/internal/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: vadimb@google.com (Vadim Berman) 31 | // 32 | // Low-level types and utilities for porting Google Mock to various 33 | // platforms. All macros ending with _ and symbols defined in an 34 | // internal namespace are subject to change without notice. Code 35 | // outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't 36 | // end with _ are part of Google Mock's public API and can be used by 37 | // code outside Google Mock. 38 | 39 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 40 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | // Most of the utilities needed for porting Google Mock are also 47 | // required for Google Test and are defined in gtest-port.h. 48 | // 49 | // Note to maintainers: to reduce code duplication, prefer adding 50 | // portability utilities to Google Test's gtest-port.h instead of 51 | // here, as Google Mock depends on Google Test. Only add a utility 52 | // here if it's truly specific to Google Mock. 53 | #include "gtest/internal/gtest-linked_ptr.h" 54 | #include "gtest/internal/gtest-port.h" 55 | #include "gmock/internal/custom/gmock-port.h" 56 | 57 | // To avoid conditional compilation everywhere, we make it 58 | // gmock-port.h's responsibility to #include the header implementing 59 | // tr1/tuple. gmock-port.h does this via gtest-port.h, which is 60 | // guaranteed to pull in the tuple header. 61 | 62 | // For MS Visual C++, check the compiler version. At least VS 2003 is 63 | // required to compile Google Mock. 64 | #if defined(_MSC_VER) && _MSC_VER < 1310 65 | # error "At least Visual C++ 2003 (7.1) is required to compile Google Mock." 66 | #endif 67 | 68 | // Macro for referencing flags. This is public as we want the user to 69 | // use this syntax to reference Google Mock flags. 70 | #define GMOCK_FLAG(name) FLAGS_gmock_##name 71 | 72 | #if !defined(GMOCK_DECLARE_bool_) 73 | 74 | // Macros for declaring flags. 75 | #define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) 76 | #define GMOCK_DECLARE_int32_(name) \ 77 | extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) 78 | #define GMOCK_DECLARE_string_(name) \ 79 | extern GTEST_API_ ::std::string GMOCK_FLAG(name) 80 | 81 | // Macros for defining flags. 82 | #define GMOCK_DEFINE_bool_(name, default_val, doc) \ 83 | GTEST_API_ bool GMOCK_FLAG(name) = (default_val) 84 | #define GMOCK_DEFINE_int32_(name, default_val, doc) \ 85 | GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) 86 | #define GMOCK_DEFINE_string_(name, default_val, doc) \ 87 | GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) 88 | 89 | #endif // !defined(GMOCK_DECLARE_bool_) 90 | 91 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 92 | -------------------------------------------------------------------------------- /pink/test/gtest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include "gtest/gtest-typed-test.h" 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | #if GTEST_HAS_TYPED_TEST_P 39 | 40 | // Skips to the first non-space char in str. Returns an empty string if str 41 | // contains only whitespace characters. 42 | static const char* SkipSpaces(const char* str) { 43 | while (IsSpace(*str)) 44 | str++; 45 | return str; 46 | } 47 | 48 | static std::vector SplitIntoTestNames(const char* src) { 49 | std::vector name_vec; 50 | src = SkipSpaces(src); 51 | for (; src != NULL; src = SkipComma(src)) { 52 | name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); 53 | } 54 | return name_vec; 55 | } 56 | 57 | // Verifies that registered_tests match the test names in 58 | // registered_tests_; returns registered_tests if successful, or 59 | // aborts the program otherwise. 60 | const char* TypedTestCasePState::VerifyRegisteredTestNames( 61 | const char* file, int line, const char* registered_tests) { 62 | typedef RegisteredTestsMap::const_iterator RegisteredTestIter; 63 | registered_ = true; 64 | 65 | std::vector name_vec = SplitIntoTestNames(registered_tests); 66 | 67 | Message errors; 68 | 69 | std::set tests; 70 | for (std::vector::const_iterator name_it = name_vec.begin(); 71 | name_it != name_vec.end(); ++name_it) { 72 | const std::string& name = *name_it; 73 | if (tests.count(name) != 0) { 74 | errors << "Test " << name << " is listed more than once.\n"; 75 | continue; 76 | } 77 | 78 | bool found = false; 79 | for (RegisteredTestIter it = registered_tests_.begin(); 80 | it != registered_tests_.end(); 81 | ++it) { 82 | if (name == it->first) { 83 | found = true; 84 | break; 85 | } 86 | } 87 | 88 | if (found) { 89 | tests.insert(name); 90 | } else { 91 | errors << "No test named " << name 92 | << " can be found in this test case.\n"; 93 | } 94 | } 95 | 96 | for (RegisteredTestIter it = registered_tests_.begin(); 97 | it != registered_tests_.end(); 98 | ++it) { 99 | if (tests.count(it->first) == 0) { 100 | errors << "You forgot to list test " << it->first << ".\n"; 101 | } 102 | } 103 | 104 | const std::string& errors_str = errors.GetString(); 105 | if (errors_str != "") { 106 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 107 | errors_str.c_str()); 108 | fflush(stderr); 109 | posix::Abort(); 110 | } 111 | 112 | return registered_tests; 113 | } 114 | 115 | #endif // GTEST_HAS_TYPED_TEST_P 116 | 117 | } // namespace internal 118 | } // namespace testing 119 | -------------------------------------------------------------------------------- /pink/test/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for building Google Test and using it in pink tests. 2 | # 3 | # SYNOPSIS: 4 | # 5 | # make [all] - makes everything. 6 | # make TARGET - makes the given target. 7 | # make clean - removes all files generated by make. 8 | 9 | # Please tweak the following variable definitions as needed by your 10 | # project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use 11 | # in your own targets but shouldn't modify. 12 | 13 | # Points to the root of Google Test, relative to where this file is. 14 | # Remember to tweak this if you move this file, or if you want to use 15 | # a copy of Google Test at a different location. 16 | GTEST_DIR = gtest 17 | 18 | # Points to the root of Google Mock, relative to where this file is. 19 | # Remember to tweak this if you move this file. 20 | GMOCK_DIR = gmock 21 | 22 | # Where to find user code. 23 | ifndef PINK_PATH 24 | $(warning Warning: missing pink path, using default) 25 | PINK_PATH=$(CURDIR)/../.. 26 | endif 27 | 28 | PINK_INCLUDE_DIR=$(PINK_PATH) 29 | PINK_LIBRARY=$(PINK_PATH)/pink/lib/libpink.a 30 | 31 | ifndef SLASH_PATH 32 | $(warning Warning: missing slash path, using default) 33 | SLASH_PATH=$(CURDIR)/../third/slash 34 | endif 35 | 36 | SLASH_INCLUDE_DIR=$(SLASH_PATH) 37 | SLASH_LIBRARY=$(SLASH_PATH)/slash/lib/libslash.a 38 | 39 | PINK_DIR = ../.. 40 | PINK_TESTS_SRC = $(PINK_DIR)/pink/src/test 41 | 42 | LDFLAGS = $(PINK_LIBRARY) $(SLASH_LIBRARY) -lpthread 43 | EXTRA_CXXFLAGS = -I$(PINK_INCLUDE_DIR) -I$(SLASH_INCLUDE_DIR) 44 | 45 | # Flags passed to the preprocessor. 46 | # Set Google Test and Google Mock's header directories as system 47 | # directories, such that the compiler doesn't generate warnings in 48 | # these headers. 49 | CPPFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include 50 | 51 | # Flags passed to the C++ compiler. 52 | CXXFLAGS += -g -Wall -Wextra -pthread -std=c++11 53 | 54 | # All tests produced by this Makefile. Remember to add new tests you 55 | # created to the list. 56 | TESTS = \ 57 | pink_thread_test \ 58 | 59 | # All Google Test headers. Usually you shouldn't change this 60 | # definition. 61 | GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ 62 | $(GTEST_DIR)/include/gtest/internal/*.h 63 | 64 | # All Google Mock headers. Note that all Google Test headers are 65 | # included here too, as they are #included by Google Mock headers. 66 | # Usually you shouldn't change this definition. 67 | GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \ 68 | $(GMOCK_DIR)/include/gmock/internal/*.h \ 69 | $(GTEST_HEADERS) 70 | 71 | # House-keeping build targets. 72 | 73 | all : $(TESTS) 74 | 75 | clean : 76 | rm -f $(TESTS) gmock.a gmock_main.a *.o 77 | 78 | check : $(TESTS) 79 | for t in $(notdir $(TESTS)); do echo "***** Running $$t"; $(CURDIR)/$$t || exit 1; done 80 | 81 | # Builds gmock.a and gmock_main.a. These libraries contain both 82 | # Google Mock and Google Test. A test should link with either gmock.a 83 | # or gmock_main.a, depending on whether it defines its own main() 84 | # function. It's fine if your test only uses features from Google 85 | # Test (and not Google Mock). 86 | 87 | # Usually you shouldn't tweak such internal variables, indicated by a 88 | # trailing _. 89 | GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) 90 | GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS) 91 | 92 | # For simplicity and to avoid depending on implementation details of 93 | # Google Mock and Google Test, the dependencies specified below are 94 | # conservative and not optimized. This is fine as Google Mock and 95 | # Google Test compile fast and for ordinary users their source rarely 96 | # changes. 97 | gtest-all.o : $(GTEST_SRCS_) 98 | $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ 99 | -c $(GTEST_DIR)/src/gtest-all.cc 100 | 101 | gmock-all.o : $(GMOCK_SRCS_) 102 | $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ 103 | -c $(GMOCK_DIR)/src/gmock-all.cc 104 | 105 | gmock_main.o : $(GMOCK_SRCS_) 106 | $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ 107 | -c $(GMOCK_DIR)/src/gmock_main.cc 108 | 109 | gmock.a : gmock-all.o gtest-all.o 110 | $(AR) $(ARFLAGS) $@ $^ 111 | 112 | gmock_main.a : gmock-all.o gtest-all.o gmock_main.o 113 | $(AR) $(ARFLAGS) $@ $^ 114 | 115 | # Builds pink tests. 116 | 117 | pink_thread_test: $(PINK_TESTS_SRC)/pink_thread_test.cc gmock_main.a 118 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(EXTRA_CXXFLAGS) $^ $(LDFLAGS) -o $@ 119 | -------------------------------------------------------------------------------- /pink/test/gtest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | 34 | #include "gtest/gtest-test-part.h" 35 | 36 | // Indicates that this translation unit is part of Google Test's 37 | // implementation. It must come before gtest-internal-inl.h is 38 | // included, or there will be a compiler error. This trick exists to 39 | // prevent the accidental inclusion of gtest-internal-inl.h in the 40 | // user's code. 41 | #define GTEST_IMPLEMENTATION_ 1 42 | #include "src/gtest-internal-inl.h" 43 | #undef GTEST_IMPLEMENTATION_ 44 | 45 | namespace testing { 46 | 47 | using internal::GetUnitTestImpl; 48 | 49 | // Gets the summary of the failure message by omitting the stack trace 50 | // in it. 51 | std::string TestPartResult::ExtractSummary(const char* message) { 52 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 53 | return stack_trace == NULL ? message : 54 | std::string(message, stack_trace); 55 | } 56 | 57 | // Prints a TestPartResult object. 58 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 59 | return os 60 | << result.file_name() << ":" << result.line_number() << ": " 61 | << (result.type() == TestPartResult::kSuccess ? "Success" : 62 | result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : 63 | "Non-fatal failure") << ":\n" 64 | << result.message() << std::endl; 65 | } 66 | 67 | // Appends a TestPartResult to the array. 68 | void TestPartResultArray::Append(const TestPartResult& result) { 69 | array_.push_back(result); 70 | } 71 | 72 | // Returns the TestPartResult at the given index (0-based). 73 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 74 | if (index < 0 || index >= size()) { 75 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 76 | internal::posix::Abort(); 77 | } 78 | 79 | return array_[index]; 80 | } 81 | 82 | // Returns the number of TestPartResult objects in the array. 83 | int TestPartResultArray::size() const { 84 | return static_cast(array_.size()); 85 | } 86 | 87 | namespace internal { 88 | 89 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 90 | : has_new_fatal_failure_(false), 91 | original_reporter_(GetUnitTestImpl()-> 92 | GetTestPartResultReporterForCurrentThread()) { 93 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 94 | } 95 | 96 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 97 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 98 | original_reporter_); 99 | } 100 | 101 | void HasNewFatalFailureHelper::ReportTestPartResult( 102 | const TestPartResult& result) { 103 | if (result.fatally_failed()) 104 | has_new_fatal_failure_ = true; 105 | original_reporter_->ReportTestPartResult(result); 106 | } 107 | 108 | } // namespace internal 109 | 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /pink/src/pb_conn.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #include "pink/include/pb_conn.h" 7 | 8 | #include 9 | #include 10 | 11 | #include "slash/include/xdebug.h" 12 | #include "pink/include/pink_define.h" 13 | 14 | namespace pink { 15 | 16 | PbConn::PbConn(const int fd, const std::string &ip_port, ServerThread *thread) : 17 | PinkConn(fd, ip_port, thread), 18 | header_len_(-1), 19 | cur_pos_(0), 20 | rbuf_len_(0), 21 | remain_packet_len_(0), 22 | connStatus_(kHeader), 23 | wbuf_len_(0), 24 | wbuf_pos_(0) { 25 | rbuf_ = reinterpret_cast(malloc(sizeof(char) * kProtoMaxMessage)); 26 | wbuf_ = reinterpret_cast(malloc(sizeof(char) * kProtoMaxMessage)); 27 | } 28 | 29 | PbConn::~PbConn() { 30 | free(rbuf_); 31 | free(wbuf_); 32 | } 33 | 34 | // Msg is [ length(COMMAND_HEADER_LENGTH) | body(length bytes) ] 35 | // step 1. kHeader, we read COMMAND_HEADER_LENGTH bytes; 36 | // step 2. kPacket, we read header_len bytes; 37 | ReadStatus PbConn::GetRequest() { 38 | while (true) { 39 | switch (connStatus_) { 40 | case kHeader: { 41 | ssize_t nread = read( 42 | fd(), rbuf_ + rbuf_len_, COMMAND_HEADER_LENGTH - rbuf_len_); 43 | if (nread == -1) { 44 | if (errno == EAGAIN) { 45 | return kReadHalf; 46 | } else { 47 | return kReadError; 48 | } 49 | } else if (nread == 0) { 50 | return kReadClose; 51 | } else { 52 | rbuf_len_ += nread; 53 | if (rbuf_len_ - cur_pos_ == COMMAND_HEADER_LENGTH) { 54 | uint32_t integer = 0; 55 | memcpy(reinterpret_cast(&integer), 56 | rbuf_ + cur_pos_, sizeof(uint32_t)); 57 | header_len_ = ntohl(integer); 58 | remain_packet_len_ = header_len_; 59 | cur_pos_ += COMMAND_HEADER_LENGTH; 60 | connStatus_ = kPacket; 61 | continue; 62 | } 63 | return kReadHalf; 64 | } 65 | } 66 | case kPacket: { 67 | if (header_len_ >= kProtoMaxMessage - COMMAND_HEADER_LENGTH) { 68 | return kFullError; 69 | } else { 70 | // read msg body 71 | ssize_t nread = read(fd(), rbuf_ + rbuf_len_, remain_packet_len_); 72 | if (nread == -1) { 73 | if (errno == EAGAIN) { 74 | return kReadHalf; 75 | } else { 76 | return kReadError; 77 | } 78 | } else if (nread == 0) { 79 | return kReadClose; 80 | } 81 | 82 | rbuf_len_ += nread; 83 | remain_packet_len_ -= nread; 84 | if (remain_packet_len_ == 0) { 85 | cur_pos_ = rbuf_len_; 86 | connStatus_ = kComplete; 87 | continue; 88 | } 89 | return kReadHalf; 90 | } 91 | } 92 | case kComplete: { 93 | if (DealMessage() != 0) { 94 | return kDealError; 95 | } 96 | connStatus_ = kHeader; 97 | cur_pos_ = 0; 98 | rbuf_len_ = 0; 99 | return kReadAll; 100 | } 101 | // Add this switch case just for delete compile warning 102 | case kBuildObuf: 103 | break; 104 | 105 | case kWriteObuf: 106 | break; 107 | } 108 | } 109 | 110 | return kReadHalf; 111 | } 112 | 113 | WriteStatus PbConn::SendReply() { 114 | if (!BuildObuf().ok()) { 115 | return kWriteError; 116 | } 117 | ssize_t nwritten = 0; 118 | while (wbuf_len_ > 0) { 119 | nwritten = write(fd(), wbuf_ + wbuf_pos_, wbuf_len_ - wbuf_pos_); 120 | if (nwritten <= 0) { 121 | break; 122 | } 123 | wbuf_pos_ += nwritten; 124 | if (wbuf_pos_ == wbuf_len_) { 125 | wbuf_len_ = 0; 126 | wbuf_pos_ = 0; 127 | } 128 | } 129 | if (nwritten == -1) { 130 | if (errno == EAGAIN) { 131 | return kWriteHalf; 132 | } else { 133 | // Here we should close the connection 134 | return kWriteError; 135 | } 136 | } 137 | if (wbuf_len_ == 0) { 138 | return kWriteAll; 139 | } else { 140 | return kWriteHalf; 141 | } 142 | } 143 | 144 | Status PbConn::BuildObuf() { 145 | wbuf_len_ = res_->ByteSize(); 146 | if (wbuf_len_ > kProtoMaxMessage - 4 147 | || !(res_->SerializeToArray(wbuf_ + 4, wbuf_len_))) { 148 | return Status::Corruption("Serialize to buffer failed"); 149 | } 150 | uint32_t u; 151 | u = htonl(wbuf_len_); 152 | memcpy(wbuf_, &u, sizeof(uint32_t)); 153 | wbuf_len_ += COMMAND_HEADER_LENGTH; 154 | 155 | return Status::OK(); 156 | } 157 | 158 | } // namespace pink 159 | -------------------------------------------------------------------------------- /pink/Makefile: -------------------------------------------------------------------------------- 1 | CLEAN_FILES = # deliberately empty, so we can append below. 2 | CXX=g++ 3 | LDFLAGS= -lpthread -lrt 4 | CXXFLAGS= -g -std=c++11 -fno-builtin-memcmp -msse -msse4.2 -pipe -fPIC 5 | PROFILING_FLAGS=-pg 6 | ARFLAGS = rs 7 | OPT= 8 | 9 | # Set the default DEBUG_LEVEL to 0 10 | DEBUG_LEVEL?=0 11 | NO_PB?=0 12 | 13 | ifeq ($(NO_PB),0) 14 | LDFLAGS+= -lprotobuf 15 | endif 16 | 17 | ifeq ($(MAKECMDGOALS),dbg) 18 | DEBUG_LEVEL=2 # compatible with rocksdb 19 | endif 20 | 21 | ifeq ($(ENABLE_SSL),1) 22 | OPT += -D__ENABLE_SSL 23 | endif 24 | 25 | # compile with -O2 if for release 26 | # if we're compiling for release, compile without debug code (-DNDEBUG) and 27 | # don't treat warnings as errors 28 | ifeq ($(DEBUG_LEVEL),0) 29 | DISABLE_WARNING_AS_ERROR=1 30 | OPT += -O2 -fno-omit-frame-pointer -DNDEBUG 31 | else 32 | $(warning Warning: Compiling in debug mode. Don't use the resulting binary in production) 33 | OPT += -O0 -D__XDEBUG__ $(PROFILING_FLAGS) 34 | endif 35 | 36 | #----------------------------------------------- 37 | 38 | SRC_DIR=src 39 | VERSION_CC=$(SRC_DIR)/build_version.cc 40 | LIB_SOURCES := $(VERSION_CC) \ 41 | $(filter-out $(VERSION_CC), $(wildcard $(SRC_DIR)/*.cc)) 42 | 43 | ifeq ($(NO_PB),1) 44 | LIB_SOURCES = $(VERSION_CC) \ 45 | $(filter-out $(VERSION_CC) $(wildcard $(SRC_DIR)/pb_*), $(wildcard $(SRC_DIR)/*.cc)) 46 | endif 47 | 48 | 49 | ifndef SLASH_PATH 50 | $(warning Warning: missing slash path, using default) 51 | SLASH_PATH=$(CURDIR)/third/slash 52 | endif 53 | SLASH_INCLUDE_DIR=$(SLASH_PATH) 54 | SLASH_LIBRARY=$(SLASH_PATH)/slash/lib/libslash.a 55 | 56 | AM_DEFAULT_VERBOSITY = 0 57 | 58 | AM_V_GEN = $(am__v_GEN_$(V)) 59 | am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) 60 | am__v_GEN_0 = @echo " GEN " $@; 61 | am__v_GEN_1 = 62 | AM_V_at = $(am__v_at_$(V)) 63 | am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) 64 | am__v_at_0 = @ 65 | am__v_at_1 = 66 | 67 | AM_V_CXX = $(am__v_CXX_$(V)) 68 | am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY)) 69 | am__v_CXX_0 = @echo " CXX " $@; 70 | am__v_CXX_1 = 71 | LD = $(CXX) 72 | AM_V_LD = $(am__v_LD_$(V)) 73 | am__v_LD_ = $(am__v_LD_$(AM_DEFAULT_VERBOSITY)) 74 | am__v_LD_0 = @echo " LD " $@; 75 | am__v_LD_1 = 76 | AM_V_AR = $(am__v_AR_$(V)) 77 | am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) 78 | am__v_AR_0 = @echo " AR " $@; 79 | am__v_AR_1 = 80 | 81 | AM_LINK = $(AM_V_LD)$(CXX) $^ -o $@ $(LDFLAGS) 82 | 83 | # This (the first rule) must depend on "all". 84 | default: all 85 | 86 | WARNING_FLAGS = -W -Wextra -Wall -Wsign-compare \ 87 | -Wno-unused-parameter -Wno-redundant-decls -Wwrite-strings \ 88 | -Wpointer-arith -Wreorder -Wswitch -Wsign-promo \ 89 | -Woverloaded-virtual -Wnon-virtual-dtor -Wno-missing-field-initializers 90 | 91 | ifndef DISABLE_WARNING_AS_ERROR 92 | WARNING_FLAGS += -Werror 93 | endif 94 | 95 | CXXFLAGS += $(WARNING_FLAGS) -I.. -I$(SLASH_INCLUDE_DIR) $(OPT) 96 | 97 | date := $(shell date +%F) 98 | git_sha := $(shell git rev-parse HEAD 2>/dev/null) 99 | gen_build_version = sed -e s/@@GIT_SHA@@/$(git_sha)/ -e s/@@GIT_DATE_TIME@@/$(date)/ $(SRC_DIR)/build_version.cc.in 100 | # Record the version of the source that we are compiling. 101 | # We keep a record of the git revision in this file. It is then built 102 | # as a regular source file as part of the compilation process. 103 | # One can run "strings executable_filename | grep _build_" to find 104 | # the version of the source that we used to build the executable file. 105 | CLEAN_FILES += $(SRC_DIR)/build_version.cc 106 | 107 | $(SRC_DIR)/build_version.cc: FORCE 108 | $(AM_V_GEN)rm -f $@-t 109 | $(AM_V_at)$(gen_build_version) > $@-t 110 | $(AM_V_at)if test -f $@; then \ 111 | cmp -s $@-t $@ && rm -f $@-t || mv -f $@-t $@; \ 112 | else mv -f $@-t $@; fi 113 | FORCE: 114 | 115 | LIBOBJECTS = $(LIB_SOURCES:.cc=.o) 116 | 117 | # if user didn't config LIBNAME, set the default 118 | ifeq ($(LIBNAME),) 119 | # we should only run pink in production with DEBUG_LEVEL 0 120 | ifeq ($(DEBUG_LEVEL),0) 121 | LIBNAME=libpink 122 | else 123 | LIBNAME=libpink_debug 124 | endif 125 | endif 126 | LIBOUTPUT = ./lib 127 | dummy := $(shell mkdir -p $(LIBOUTPUT)) 128 | LIBRARY = $(LIBOUTPUT)/${LIBNAME}.a 129 | 130 | TESTS = test/pink_thread_test 131 | 132 | .PHONY: clean dbg static_lib all example 133 | 134 | all: $(LIBRARY) 135 | 136 | static_lib: $(LIBRARY) 137 | 138 | example: 139 | @make -C examples PINK_PATH=$(CURDIR)/.. SLASH_PATH=$(SLASH_PATH) DEBUG_LEVEL=$(DEBUG_LEVEL) 140 | 141 | check: $(LIBRARY) 142 | @make -C test PINK_PATH=$(CURDIR)/.. SLASH_PATH=$(SLASH_PATH) 143 | for t in $(notdir $(TESTS)); do echo "***** Running $$t"; ./test/$$t || exit 1; done 144 | 145 | dbg: $(LIBRARY) 146 | 147 | $(LIBRARY): $(LIBOBJECTS) 148 | $(AM_V_AR)rm -f $@ 149 | $(AM_V_at)$(AR) $(ARFLAGS) $@ $(LIBOBJECTS) 150 | 151 | clean: 152 | make -C ./examples clean 153 | rm -f $(LIBRARY) 154 | rm -rf $(CLEAN_FILES) 155 | rm -rf $(LIBOUTPUT) 156 | rm -f $(TESTS) 157 | find . -name "*.[oda]*" ! -path "./third/*" -exec rm -f {} \; 158 | find . -type f -regex ".*\.\(\(gcda\)\|\(gcno\)\)" -exec rm {} \; 159 | 160 | %.o: %.cc 161 | $(AM_V_CXX)$(CXX) $(CXXFLAGS) -c $< -o $@ 162 | 163 | %.d: %.cc 164 | @set -e; rm -f $@; $(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \ 165 | sed 's,\($(notdir $*)\)\.o[ :]*,$(SRC_DIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \ 166 | rm -f $@.$$$$ 167 | 168 | ifneq ($(MAKECMDGOALS),clean) 169 | -include $(LIBOBJECTS:.o=.d) 170 | endif 171 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $$ This is a Pump source file. Please use Pump to convert it to 3 | $$ gmock-generated-function-mockers.h. 4 | $$ 5 | $var n = 10 $$ The maximum arity we support. 6 | // Copyright 2007, Google Inc. 7 | // All rights reserved. 8 | // 9 | // Redistribution and use in source and binary forms, with or without 10 | // modification, are permitted provided that the following conditions are 11 | // met: 12 | // 13 | // * Redistributions of source code must retain the above copyright 14 | // notice, this list of conditions and the following disclaimer. 15 | // * Redistributions in binary form must reproduce the above 16 | // copyright notice, this list of conditions and the following disclaimer 17 | // in the documentation and/or other materials provided with the 18 | // distribution. 19 | // * Neither the name of Google Inc. nor the names of its 20 | // contributors may be used to endorse or promote products derived from 21 | // this software without specific prior written permission. 22 | // 23 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | // 35 | // Author: wan@google.com (Zhanyong Wan) 36 | 37 | // Google Mock - a framework for writing C++ mock classes. 38 | // 39 | // This file contains template meta-programming utility classes needed 40 | // for implementing Google Mock. 41 | 42 | #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ 43 | #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ 44 | 45 | #include "gmock/internal/gmock-port.h" 46 | 47 | namespace testing { 48 | 49 | template 50 | class Matcher; 51 | 52 | namespace internal { 53 | 54 | // An IgnoredValue object can be implicitly constructed from ANY value. 55 | // This is used in implementing the IgnoreResult(a) action. 56 | class IgnoredValue { 57 | public: 58 | // This constructor template allows any value to be implicitly 59 | // converted to IgnoredValue. The object has no data member and 60 | // doesn't try to remember anything about the argument. We 61 | // deliberately omit the 'explicit' keyword in order to allow the 62 | // conversion to be implicit. 63 | template 64 | IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) 65 | }; 66 | 67 | // MatcherTuple::type is a tuple type where each field is a Matcher 68 | // for the corresponding field in tuple type T. 69 | template 70 | struct MatcherTuple; 71 | 72 | 73 | $range i 0..n 74 | $for i [[ 75 | $range j 1..i 76 | $var typename_As = [[$for j, [[typename A$j]]]] 77 | $var As = [[$for j, [[A$j]]]] 78 | $var matcher_As = [[$for j, [[Matcher]]]] 79 | template <$typename_As> 80 | struct MatcherTuple< ::testing::tuple<$As> > { 81 | typedef ::testing::tuple<$matcher_As > type; 82 | }; 83 | 84 | 85 | ]] 86 | // Template struct Function, where F must be a function type, contains 87 | // the following typedefs: 88 | // 89 | // Result: the function's return type. 90 | // ArgumentN: the type of the N-th argument, where N starts with 1. 91 | // ArgumentTuple: the tuple type consisting of all parameters of F. 92 | // ArgumentMatcherTuple: the tuple type consisting of Matchers for all 93 | // parameters of F. 94 | // MakeResultVoid: the function type obtained by substituting void 95 | // for the return type of F. 96 | // MakeResultIgnoredValue: 97 | // the function type obtained by substituting Something 98 | // for the return type of F. 99 | template 100 | struct Function; 101 | 102 | template 103 | struct Function { 104 | typedef R Result; 105 | typedef ::testing::tuple<> ArgumentTuple; 106 | typedef typename MatcherTuple::type ArgumentMatcherTuple; 107 | typedef void MakeResultVoid(); 108 | typedef IgnoredValue MakeResultIgnoredValue(); 109 | }; 110 | 111 | 112 | $range i 1..n 113 | $for i [[ 114 | $range j 1..i 115 | $var typename_As = [[$for j [[, typename A$j]]]] 116 | $var As = [[$for j, [[A$j]]]] 117 | $var matcher_As = [[$for j, [[Matcher]]]] 118 | $range k 1..i-1 119 | $var prev_As = [[$for k, [[A$k]]]] 120 | template 121 | struct Function 122 | : Function { 123 | typedef A$i Argument$i; 124 | typedef ::testing::tuple<$As> ArgumentTuple; 125 | typedef typename MatcherTuple::type ArgumentMatcherTuple; 126 | typedef void MakeResultVoid($As); 127 | typedef IgnoredValue MakeResultIgnoredValue($As); 128 | }; 129 | 130 | 131 | ]] 132 | } // namespace internal 133 | 134 | } // namespace testing 135 | 136 | #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ 137 | -------------------------------------------------------------------------------- /pink/test/gmock/src/gmock-cardinalities.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file implements cardinalities. 35 | 36 | #include "gmock/gmock-cardinalities.h" 37 | 38 | #include 39 | #include // NOLINT 40 | #include 41 | #include 42 | #include "gmock/internal/gmock-internal-utils.h" 43 | #include "gtest/gtest.h" 44 | 45 | namespace testing { 46 | 47 | namespace { 48 | 49 | // Implements the Between(m, n) cardinality. 50 | class BetweenCardinalityImpl : public CardinalityInterface { 51 | public: 52 | BetweenCardinalityImpl(int min, int max) 53 | : min_(min >= 0 ? min : 0), 54 | max_(max >= min_ ? max : min_) { 55 | std::stringstream ss; 56 | if (min < 0) { 57 | ss << "The invocation lower bound must be >= 0, " 58 | << "but is actually " << min << "."; 59 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 60 | } else if (max < 0) { 61 | ss << "The invocation upper bound must be >= 0, " 62 | << "but is actually " << max << "."; 63 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 64 | } else if (min > max) { 65 | ss << "The invocation upper bound (" << max 66 | << ") must be >= the invocation lower bound (" << min 67 | << ")."; 68 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 69 | } 70 | } 71 | 72 | // Conservative estimate on the lower/upper bound of the number of 73 | // calls allowed. 74 | virtual int ConservativeLowerBound() const { return min_; } 75 | virtual int ConservativeUpperBound() const { return max_; } 76 | 77 | virtual bool IsSatisfiedByCallCount(int call_count) const { 78 | return min_ <= call_count && call_count <= max_; 79 | } 80 | 81 | virtual bool IsSaturatedByCallCount(int call_count) const { 82 | return call_count >= max_; 83 | } 84 | 85 | virtual void DescribeTo(::std::ostream* os) const; 86 | 87 | private: 88 | const int min_; 89 | const int max_; 90 | 91 | GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); 92 | }; 93 | 94 | // Formats "n times" in a human-friendly way. 95 | inline internal::string FormatTimes(int n) { 96 | if (n == 1) { 97 | return "once"; 98 | } else if (n == 2) { 99 | return "twice"; 100 | } else { 101 | std::stringstream ss; 102 | ss << n << " times"; 103 | return ss.str(); 104 | } 105 | } 106 | 107 | // Describes the Between(m, n) cardinality in human-friendly text. 108 | void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { 109 | if (min_ == 0) { 110 | if (max_ == 0) { 111 | *os << "never called"; 112 | } else if (max_ == INT_MAX) { 113 | *os << "called any number of times"; 114 | } else { 115 | *os << "called at most " << FormatTimes(max_); 116 | } 117 | } else if (min_ == max_) { 118 | *os << "called " << FormatTimes(min_); 119 | } else if (max_ == INT_MAX) { 120 | *os << "called at least " << FormatTimes(min_); 121 | } else { 122 | // 0 < min_ < max_ < INT_MAX 123 | *os << "called between " << min_ << " and " << max_ << " times"; 124 | } 125 | } 126 | 127 | } // Unnamed namespace 128 | 129 | // Describes the given call count to an ostream. 130 | void Cardinality::DescribeActualCallCountTo(int actual_call_count, 131 | ::std::ostream* os) { 132 | if (actual_call_count > 0) { 133 | *os << "called " << FormatTimes(actual_call_count); 134 | } else { 135 | *os << "never called"; 136 | } 137 | } 138 | 139 | // Creates a cardinality that allows at least n calls. 140 | GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } 141 | 142 | // Creates a cardinality that allows at most n calls. 143 | GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } 144 | 145 | // Creates a cardinality that allows any number of calls. 146 | GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } 147 | 148 | // Creates a cardinality that allows between min and max calls. 149 | GTEST_API_ Cardinality Between(int min, int max) { 150 | return Cardinality(new BetweenCardinalityImpl(min, max)); 151 | } 152 | 153 | // Creates a cardinality that allows exactly n calls. 154 | GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } 155 | 156 | } // namespace testing 157 | -------------------------------------------------------------------------------- /pink/test/gmock/CHANGES: -------------------------------------------------------------------------------- 1 | Changes for 1.7.0: 2 | 3 | * All new improvements in Google Test 1.7.0. 4 | * New feature: matchers DoubleNear(), FloatNear(), 5 | NanSensitiveDoubleNear(), NanSensitiveFloatNear(), 6 | UnorderedElementsAre(), UnorderedElementsAreArray(), WhenSorted(), 7 | WhenSortedBy(), IsEmpty(), and SizeIs(). 8 | * Improvement: Google Mock can now be built as a DLL. 9 | * Improvement: when compiled by a C++11 compiler, matchers AllOf() 10 | and AnyOf() can accept an arbitrary number of matchers. 11 | * Improvement: when compiled by a C++11 compiler, matchers 12 | ElementsAreArray() can accept an initializer list. 13 | * Improvement: when exceptions are enabled, a mock method with no 14 | default action now throws instead crashing the test. 15 | * Improvement: added class testing::StringMatchResultListener to aid 16 | definition of composite matchers. 17 | * Improvement: function return types used in MOCK_METHOD*() macros can 18 | now contain unprotected commas. 19 | * Improvement (potentially breaking): EXPECT_THAT() and ASSERT_THAT() 20 | are now more strict in ensuring that the value type and the matcher 21 | type are compatible, catching potential bugs in tests. 22 | * Improvement: Pointee() now works on an optional. 23 | * Improvement: the ElementsAreArray() matcher can now take a vector or 24 | iterator range as input, and makes a copy of its input elements 25 | before the conversion to a Matcher. 26 | * Improvement: the Google Mock Generator can now generate mocks for 27 | some class templates. 28 | * Bug fix: mock object destruction triggerred by another mock object's 29 | destruction no longer hangs. 30 | * Improvement: Google Mock Doctor works better with newer Clang and 31 | GCC now. 32 | * Compatibility fixes. 33 | * Bug/warning fixes. 34 | 35 | Changes for 1.6.0: 36 | 37 | * Compilation is much faster and uses much less memory, especially 38 | when the constructor and destructor of a mock class are moved out of 39 | the class body. 40 | * New matchers: Pointwise(), Each(). 41 | * New actions: ReturnPointee() and ReturnRefOfCopy(). 42 | * CMake support. 43 | * Project files for Visual Studio 2010. 44 | * AllOf() and AnyOf() can handle up-to 10 arguments now. 45 | * Google Mock doctor understands Clang error messages now. 46 | * SetArgPointee<> now accepts string literals. 47 | * gmock_gen.py handles storage specifier macros and template return 48 | types now. 49 | * Compatibility fixes. 50 | * Bug fixes and implementation clean-ups. 51 | * Potentially incompatible changes: disables the harmful 'make install' 52 | command in autotools. 53 | 54 | Potentially breaking changes: 55 | 56 | * The description string for MATCHER*() changes from Python-style 57 | interpolation to an ordinary C++ string expression. 58 | * SetArgumentPointee is deprecated in favor of SetArgPointee. 59 | * Some non-essential project files for Visual Studio 2005 are removed. 60 | 61 | Changes for 1.5.0: 62 | 63 | * New feature: Google Mock can be safely used in multi-threaded tests 64 | on platforms having pthreads. 65 | * New feature: function for printing a value of arbitrary type. 66 | * New feature: function ExplainMatchResult() for easy definition of 67 | composite matchers. 68 | * The new matcher API lets user-defined matchers generate custom 69 | explanations more directly and efficiently. 70 | * Better failure messages all around. 71 | * NotNull() and IsNull() now work with smart pointers. 72 | * Field() and Property() now work when the matcher argument is a pointer 73 | passed by reference. 74 | * Regular expression matchers on all platforms. 75 | * Added GCC 4.0 support for Google Mock Doctor. 76 | * Added gmock_all_test.cc for compiling most Google Mock tests 77 | in a single file. 78 | * Significantly cleaned up compiler warnings. 79 | * Bug fixes, better test coverage, and implementation clean-ups. 80 | 81 | Potentially breaking changes: 82 | 83 | * Custom matchers defined using MatcherInterface or MakePolymorphicMatcher() 84 | need to be updated after upgrading to Google Mock 1.5.0; matchers defined 85 | using MATCHER or MATCHER_P* aren't affected. 86 | * Dropped support for 'make install'. 87 | 88 | Changes for 1.4.0 (we skipped 1.2.* and 1.3.* to match the version of 89 | Google Test): 90 | 91 | * Works in more environments: Symbian and minGW, Visual C++ 7.1. 92 | * Lighter weight: comes with our own implementation of TR1 tuple (no 93 | more dependency on Boost!). 94 | * New feature: --gmock_catch_leaked_mocks for detecting leaked mocks. 95 | * New feature: ACTION_TEMPLATE for defining templatized actions. 96 | * New feature: the .After() clause for specifying expectation order. 97 | * New feature: the .With() clause for for specifying inter-argument 98 | constraints. 99 | * New feature: actions ReturnArg(), ReturnNew(...), and 100 | DeleteArg(). 101 | * New feature: matchers Key(), Pair(), Args<...>(), AllArgs(), IsNull(), 102 | and Contains(). 103 | * New feature: utility class MockFunction, useful for checkpoints, etc. 104 | * New feature: functions Value(x, m) and SafeMatcherCast(m). 105 | * New feature: copying a mock object is rejected at compile time. 106 | * New feature: a script for fusing all Google Mock and Google Test 107 | source files for easy deployment. 108 | * Improved the Google Mock doctor to diagnose more diseases. 109 | * Improved the Google Mock generator script. 110 | * Compatibility fixes for Mac OS X and gcc. 111 | * Bug fixes and implementation clean-ups. 112 | 113 | Changes for 1.1.0: 114 | 115 | * New feature: ability to use Google Mock with any testing framework. 116 | * New feature: macros for easily defining new matchers 117 | * New feature: macros for easily defining new actions. 118 | * New feature: more container matchers. 119 | * New feature: actions for accessing function arguments and throwing 120 | exceptions. 121 | * Improved the Google Mock doctor script for diagnosing compiler errors. 122 | * Bug fixes and implementation clean-ups. 123 | 124 | Changes for 1.0.0: 125 | 126 | * Initial Open Source release of Google Mock 127 | -------------------------------------------------------------------------------- /pink/include/http_conn.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015-present, Qihoo, Inc. All rights reserved. 2 | // This source code is licensed under the BSD-style license found in the 3 | // LICENSE file in the root directory of this source tree. An additional grant 4 | // of patent rights can be found in the PATENTS file in the same directory. 5 | 6 | #ifndef PINK_INCLUDE_HTTP_CONN_H_ 7 | #define PINK_INCLUDE_HTTP_CONN_H_ 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "slash/include/slash_status.h" 14 | #include "slash/include/xdebug.h" 15 | 16 | #include "pink/include/pink_conn.h" 17 | #include "pink/include/pink_define.h" 18 | #include "pink/src/pink_util.h" 19 | 20 | namespace pink { 21 | 22 | class HTTPConn; 23 | 24 | class HTTPRequest { 25 | public: 26 | const std::string url() const; 27 | const std::string path() const; 28 | const std::string query_value(const std::string& field) const; 29 | const std::map query_params() const; 30 | const std::map postform_params() const; 31 | const std::map headers() const; 32 | const std::string postform_value(const std::string& field) const; 33 | const std::string method() const; 34 | const std::string content_type() const; 35 | 36 | const std::string client_ip_port() const; 37 | 38 | void Reset(); 39 | void Dump() const; 40 | 41 | private: 42 | friend class HTTPConn; 43 | explicit HTTPRequest(HTTPConn* conn); 44 | ~HTTPRequest(); 45 | 46 | HTTPConn* conn_; 47 | 48 | std::string method_; 49 | std::string url_; 50 | std::string path_; 51 | std::string version_; 52 | std::string content_type_; 53 | bool reply_100continue_; 54 | std::map postform_params_; 55 | std::map query_params_; 56 | std::map headers_; 57 | 58 | std::string client_ip_port_; 59 | 60 | enum RequestParserStatus { 61 | kHeaderMethod, 62 | kHeaderPath, 63 | kHeaderVersion, 64 | kHeaderParamKey, 65 | kHeaderParamValue, 66 | }; 67 | 68 | enum RequestStatus { 69 | kNewRequest, 70 | kHeaderReceiving, 71 | kBodyReceiving, 72 | kBodyReceived, 73 | }; 74 | 75 | RequestStatus req_status_; 76 | RequestParserStatus parse_status_; 77 | 78 | char* rbuf_; 79 | uint64_t rbuf_pos_; 80 | uint64_t remain_recv_len_; 81 | 82 | ReadStatus ReadData(); 83 | int ParseHeader(); 84 | 85 | ReadStatus DoRead(); 86 | bool ParseHeadFromArray(const char* data, const int size); 87 | bool ParseGetUrl(); 88 | bool ParseHeadLine(const char* data, int line_start, int line_end); 89 | bool ParseParameters(const std::string data, size_t line_start = 0); 90 | }; 91 | 92 | class HTTPResponse { 93 | public: 94 | void SetStatusCode(int code); 95 | void SetHeaders(const std::string& key, const std::string& value); 96 | void SetHeaders(const std::string& key, const size_t value); 97 | void SetContentLength(uint64_t size); 98 | 99 | void Reset(); 100 | bool Finished(); 101 | 102 | private: 103 | friend class HTTPConn; 104 | HTTPConn* conn_; 105 | 106 | explicit HTTPResponse(HTTPConn* conn); 107 | ~HTTPResponse(); 108 | 109 | enum ResponseStatus { 110 | kPrepareHeader, 111 | kSendingHeader, 112 | kSendingBody, 113 | }; 114 | 115 | ResponseStatus resp_status_; 116 | 117 | char* wbuf_; 118 | int64_t buf_len_; 119 | int64_t wbuf_pos_; 120 | 121 | uint64_t remain_send_len_; 122 | bool finished_; 123 | 124 | int status_code_; 125 | std::map headers_; 126 | 127 | bool Flush(); 128 | bool SerializeHeader(); 129 | }; 130 | 131 | class HTTPHandles { 132 | public: 133 | // You need implement these handles. 134 | /* 135 | * We have parsed HTTP request for now, 136 | * then HandleRequest(req, resp) will be called. 137 | * Return true if reply needed, and then handle response header and body 138 | * by functions below, otherwise false. 139 | */ 140 | virtual bool HandleRequest(const HTTPRequest* req) = 0; 141 | /* 142 | * ReadBodyData(...) will be called if there are data follow up, 143 | * We deliver data just once. 144 | */ 145 | virtual void HandleBodyData(const char* data, size_t data_size) = 0; 146 | 147 | /* 148 | * Fill response headers in this handle when body received. 149 | * You MUST set Content-Length by means of calling resp->SetContentLength(num). 150 | * Besides, resp->SetStatusCode(code) should be called either. 151 | */ 152 | virtual void PrepareResponse(HTTPResponse* resp) = 0; 153 | /* 154 | * Fill write buffer 'buf' in this handle, and should not exceed 'max_size'. 155 | * Return actual size filled. 156 | * Return -2 if has written all 157 | * Return Other as Error and close connection 158 | */ 159 | virtual int WriteResponseBody(char* buf, size_t max_size) = 0; 160 | 161 | // Close handle 162 | virtual void HandleConnClosed() { 163 | } 164 | 165 | HTTPHandles() { 166 | } 167 | virtual ~HTTPHandles() { 168 | } 169 | 170 | protected: 171 | /* 172 | * Assigned in ServerHandle's CreateWorkerSpecificData 173 | * Used for handles above 174 | */ 175 | void* worker_specific_data_; 176 | 177 | private: 178 | friend class HTTPConn; 179 | 180 | /* 181 | * No allowed copy and copy assign 182 | */ 183 | HTTPHandles(const HTTPHandles&); 184 | void operator=(const HTTPHandles&); 185 | }; 186 | 187 | class HTTPConn: public PinkConn { 188 | public: 189 | HTTPConn(const int fd, const std::string &ip_port, 190 | ServerThread *sthread, std::shared_ptr handles_, 191 | void* worker_specific_data); 192 | ~HTTPConn(); 193 | 194 | virtual ReadStatus GetRequest() override; 195 | virtual WriteStatus SendReply() override; 196 | 197 | private: 198 | friend class HTTPRequest; 199 | friend class HTTPResponse; 200 | 201 | HTTPRequest* request_; 202 | HTTPResponse* response_; 203 | 204 | #ifdef __ENABLE_SSL 205 | bool security_; 206 | #endif 207 | 208 | std::shared_ptr handles_; 209 | }; 210 | 211 | } // namespace pink 212 | 213 | #endif // PINK_INCLUDE_HTTP_CONN_H_ 214 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/gmock-cardinalities.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | // Google Mock - a framework for writing C++ mock classes. 33 | // 34 | // This file implements some commonly used cardinalities. More 35 | // cardinalities can be defined by the user implementing the 36 | // CardinalityInterface interface if necessary. 37 | 38 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 39 | #define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 40 | 41 | #include 42 | #include // NOLINT 43 | #include "gmock/internal/gmock-port.h" 44 | #include "gtest/gtest.h" 45 | 46 | namespace testing { 47 | 48 | // To implement a cardinality Foo, define: 49 | // 1. a class FooCardinality that implements the 50 | // CardinalityInterface interface, and 51 | // 2. a factory function that creates a Cardinality object from a 52 | // const FooCardinality*. 53 | // 54 | // The two-level delegation design follows that of Matcher, providing 55 | // consistency for extension developers. It also eases ownership 56 | // management as Cardinality objects can now be copied like plain values. 57 | 58 | // The implementation of a cardinality. 59 | class CardinalityInterface { 60 | public: 61 | virtual ~CardinalityInterface() {} 62 | 63 | // Conservative estimate on the lower/upper bound of the number of 64 | // calls allowed. 65 | virtual int ConservativeLowerBound() const { return 0; } 66 | virtual int ConservativeUpperBound() const { return INT_MAX; } 67 | 68 | // Returns true iff call_count calls will satisfy this cardinality. 69 | virtual bool IsSatisfiedByCallCount(int call_count) const = 0; 70 | 71 | // Returns true iff call_count calls will saturate this cardinality. 72 | virtual bool IsSaturatedByCallCount(int call_count) const = 0; 73 | 74 | // Describes self to an ostream. 75 | virtual void DescribeTo(::std::ostream* os) const = 0; 76 | }; 77 | 78 | // A Cardinality is a copyable and IMMUTABLE (except by assignment) 79 | // object that specifies how many times a mock function is expected to 80 | // be called. The implementation of Cardinality is just a linked_ptr 81 | // to const CardinalityInterface, so copying is fairly cheap. 82 | // Don't inherit from Cardinality! 83 | class GTEST_API_ Cardinality { 84 | public: 85 | // Constructs a null cardinality. Needed for storing Cardinality 86 | // objects in STL containers. 87 | Cardinality() {} 88 | 89 | // Constructs a Cardinality from its implementation. 90 | explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} 91 | 92 | // Conservative estimate on the lower/upper bound of the number of 93 | // calls allowed. 94 | int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } 95 | int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } 96 | 97 | // Returns true iff call_count calls will satisfy this cardinality. 98 | bool IsSatisfiedByCallCount(int call_count) const { 99 | return impl_->IsSatisfiedByCallCount(call_count); 100 | } 101 | 102 | // Returns true iff call_count calls will saturate this cardinality. 103 | bool IsSaturatedByCallCount(int call_count) const { 104 | return impl_->IsSaturatedByCallCount(call_count); 105 | } 106 | 107 | // Returns true iff call_count calls will over-saturate this 108 | // cardinality, i.e. exceed the maximum number of allowed calls. 109 | bool IsOverSaturatedByCallCount(int call_count) const { 110 | return impl_->IsSaturatedByCallCount(call_count) && 111 | !impl_->IsSatisfiedByCallCount(call_count); 112 | } 113 | 114 | // Describes self to an ostream 115 | void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } 116 | 117 | // Describes the given actual call count to an ostream. 118 | static void DescribeActualCallCountTo(int actual_call_count, 119 | ::std::ostream* os); 120 | 121 | private: 122 | internal::linked_ptr impl_; 123 | }; 124 | 125 | // Creates a cardinality that allows at least n calls. 126 | GTEST_API_ Cardinality AtLeast(int n); 127 | 128 | // Creates a cardinality that allows at most n calls. 129 | GTEST_API_ Cardinality AtMost(int n); 130 | 131 | // Creates a cardinality that allows any number of calls. 132 | GTEST_API_ Cardinality AnyNumber(); 133 | 134 | // Creates a cardinality that allows between min and max calls. 135 | GTEST_API_ Cardinality Between(int min, int max); 136 | 137 | // Creates a cardinality that allows exactly n calls. 138 | GTEST_API_ Cardinality Exactly(int n); 139 | 140 | // Creates a cardinality from its implementation. 141 | inline Cardinality MakeCardinality(const CardinalityInterface* c) { 142 | return Cardinality(c); 143 | } 144 | 145 | } // namespace testing 146 | 147 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 148 | -------------------------------------------------------------------------------- /pink/test/gmock/include/gmock/gmock-generated-nice-strict.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $$ This is a Pump source file. Please use Pump to convert it to 3 | $$ gmock-generated-nice-strict.h. 4 | $$ 5 | $var n = 10 $$ The maximum arity we support. 6 | // Copyright 2008, Google Inc. 7 | // All rights reserved. 8 | // 9 | // Redistribution and use in source and binary forms, with or without 10 | // modification, are permitted provided that the following conditions are 11 | // met: 12 | // 13 | // * Redistributions of source code must retain the above copyright 14 | // notice, this list of conditions and the following disclaimer. 15 | // * Redistributions in binary form must reproduce the above 16 | // copyright notice, this list of conditions and the following disclaimer 17 | // in the documentation and/or other materials provided with the 18 | // distribution. 19 | // * Neither the name of Google Inc. nor the names of its 20 | // contributors may be used to endorse or promote products derived from 21 | // this software without specific prior written permission. 22 | // 23 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | // 35 | // Author: wan@google.com (Zhanyong Wan) 36 | 37 | // Implements class templates NiceMock, NaggyMock, and StrictMock. 38 | // 39 | // Given a mock class MockFoo that is created using Google Mock, 40 | // NiceMock is a subclass of MockFoo that allows 41 | // uninteresting calls (i.e. calls to mock methods that have no 42 | // EXPECT_CALL specs), NaggyMock is a subclass of MockFoo 43 | // that prints a warning when an uninteresting call occurs, and 44 | // StrictMock is a subclass of MockFoo that treats all 45 | // uninteresting calls as errors. 46 | // 47 | // Currently a mock is naggy by default, so MockFoo and 48 | // NaggyMock behave like the same. However, we will soon 49 | // switch the default behavior of mocks to be nice, as that in general 50 | // leads to more maintainable tests. When that happens, MockFoo will 51 | // stop behaving like NaggyMock and start behaving like 52 | // NiceMock. 53 | // 54 | // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of 55 | // their respective base class, with up-to $n arguments. Therefore 56 | // you can write NiceMock(5, "a") to construct a nice mock 57 | // where MockFoo has a constructor that accepts (int, const char*), 58 | // for example. 59 | // 60 | // A known limitation is that NiceMock, NaggyMock, 61 | // and StrictMock only works for mock methods defined using 62 | // the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. 63 | // If a mock method is defined in a base class of MockFoo, the "nice" 64 | // or "strict" modifier may not affect it, depending on the compiler. 65 | // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT 66 | // supported. 67 | // 68 | // Another known limitation is that the constructors of the base mock 69 | // cannot have arguments passed by non-const reference, which are 70 | // banned by the Google C++ style guide anyway. 71 | 72 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ 73 | #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ 74 | 75 | #include "gmock/gmock-spec-builders.h" 76 | #include "gmock/internal/gmock-port.h" 77 | 78 | namespace testing { 79 | 80 | $range kind 0..2 81 | $for kind [[ 82 | 83 | $var clazz=[[$if kind==0 [[NiceMock]] 84 | $elif kind==1 [[NaggyMock]] 85 | $else [[StrictMock]]]] 86 | 87 | $var method=[[$if kind==0 [[AllowUninterestingCalls]] 88 | $elif kind==1 [[WarnUninterestingCalls]] 89 | $else [[FailUninterestingCalls]]]] 90 | 91 | template 92 | class $clazz : public MockClass { 93 | public: 94 | // We don't factor out the constructor body to a common method, as 95 | // we have to avoid a possible clash with members of MockClass. 96 | $clazz() { 97 | ::testing::Mock::$method( 98 | internal::ImplicitCast_(this)); 99 | } 100 | 101 | // C++ doesn't (yet) allow inheritance of constructors, so we have 102 | // to define it for each arity. 103 | template 104 | explicit $clazz(const A1& a1) : MockClass(a1) { 105 | ::testing::Mock::$method( 106 | internal::ImplicitCast_(this)); 107 | } 108 | 109 | $range i 2..n 110 | $for i [[ 111 | $range j 1..i 112 | template <$for j, [[typename A$j]]> 113 | $clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) { 114 | ::testing::Mock::$method( 115 | internal::ImplicitCast_(this)); 116 | } 117 | 118 | 119 | ]] 120 | virtual ~$clazz() { 121 | ::testing::Mock::UnregisterCallReaction( 122 | internal::ImplicitCast_(this)); 123 | } 124 | 125 | private: 126 | GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz); 127 | }; 128 | 129 | ]] 130 | 131 | // The following specializations catch some (relatively more common) 132 | // user errors of nesting nice and strict mocks. They do NOT catch 133 | // all possible errors. 134 | 135 | // These specializations are declared but not defined, as NiceMock, 136 | // NaggyMock, and StrictMock cannot be nested. 137 | 138 | template 139 | class NiceMock >; 140 | template 141 | class NiceMock >; 142 | template 143 | class NiceMock >; 144 | 145 | template 146 | class NaggyMock >; 147 | template 148 | class NaggyMock >; 149 | template 150 | class NaggyMock >; 151 | 152 | template 153 | class StrictMock >; 154 | template 155 | class StrictMock >; 156 | template 157 | class StrictMock >; 158 | 159 | } // namespace testing 160 | 161 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ 162 | -------------------------------------------------------------------------------- /pink/test/gtest/CHANGES: -------------------------------------------------------------------------------- 1 | Changes for 1.7.0: 2 | 3 | * New feature: death tests are supported on OpenBSD and in iOS 4 | simulator now. 5 | * New feature: Google Test now implements a protocol to allow 6 | a test runner to detect that a test program has exited 7 | prematurely and report it as a failure (before it would be 8 | falsely reported as a success if the exit code is 0). 9 | * New feature: Test::RecordProperty() can now be used outside of the 10 | lifespan of a test method, in which case it will be attributed to 11 | the current test case or the test program in the XML report. 12 | * New feature (potentially breaking): --gtest_list_tests now prints 13 | the type parameters and value parameters for each test. 14 | * Improvement: char pointers and char arrays are now escaped properly 15 | in failure messages. 16 | * Improvement: failure summary in XML reports now includes file and 17 | line information. 18 | * Improvement: the XML element now has a timestamp attribute. 19 | * Improvement: When --gtest_filter is specified, XML report now doesn't 20 | contain information about tests that are filtered out. 21 | * Fixed the bug where long --gtest_filter flag values are truncated in 22 | death tests. 23 | * Potentially breaking change: RUN_ALL_TESTS() is now implemented as a 24 | function instead of a macro in order to work better with Clang. 25 | * Compatibility fixes with C++ 11 and various platforms. 26 | * Bug/warning fixes. 27 | 28 | Changes for 1.6.0: 29 | 30 | * New feature: ADD_FAILURE_AT() for reporting a test failure at the 31 | given source location -- useful for writing testing utilities. 32 | * New feature: the universal value printer is moved from Google Mock 33 | to Google Test. 34 | * New feature: type parameters and value parameters are reported in 35 | the XML report now. 36 | * A gtest_disable_pthreads CMake option. 37 | * Colored output works in GNU Screen sessions now. 38 | * Parameters of value-parameterized tests are now printed in the 39 | textual output. 40 | * Failures from ad hoc test assertions run before RUN_ALL_TESTS() are 41 | now correctly reported. 42 | * Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to 43 | ostream. 44 | * More complete handling of exceptions. 45 | * GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter 46 | name is already used by another library. 47 | * --gtest_catch_exceptions is now true by default, allowing a test 48 | program to continue after an exception is thrown. 49 | * Value-parameterized test fixtures can now derive from Test and 50 | WithParamInterface separately, easing conversion of legacy tests. 51 | * Death test messages are clearly marked to make them more 52 | distinguishable from other messages. 53 | * Compatibility fixes for Android, Google Native Client, MinGW, HP UX, 54 | PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), 55 | IBM XL C++ (Visual Age C++), and C++0x. 56 | * Bug fixes and implementation clean-ups. 57 | * Potentially incompatible changes: disables the harmful 'make install' 58 | command in autotools. 59 | 60 | Changes for 1.5.0: 61 | 62 | * New feature: assertions can be safely called in multiple threads 63 | where the pthreads library is available. 64 | * New feature: predicates used inside EXPECT_TRUE() and friends 65 | can now generate custom failure messages. 66 | * New feature: Google Test can now be compiled as a DLL. 67 | * New feature: fused source files are included. 68 | * New feature: prints help when encountering unrecognized Google Test flags. 69 | * Experimental feature: CMake build script (requires CMake 2.6.4+). 70 | * Experimental feature: the Pump script for meta programming. 71 | * double values streamed to an assertion are printed with enough precision 72 | to differentiate any two different values. 73 | * Google Test now works on Solaris and AIX. 74 | * Build and test script improvements. 75 | * Bug fixes and implementation clean-ups. 76 | 77 | Potentially breaking changes: 78 | 79 | * Stopped supporting VC++ 7.1 with exceptions disabled. 80 | * Dropped support for 'make install'. 81 | 82 | Changes for 1.4.0: 83 | 84 | * New feature: the event listener API 85 | * New feature: test shuffling 86 | * New feature: the XML report format is closer to junitreport and can 87 | be parsed by Hudson now. 88 | * New feature: when a test runs under Visual Studio, its failures are 89 | integrated in the IDE. 90 | * New feature: /MD(d) versions of VC++ projects. 91 | * New feature: elapsed time for the tests is printed by default. 92 | * New feature: comes with a TR1 tuple implementation such that Boost 93 | is no longer needed for Combine(). 94 | * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. 95 | * New feature: the Xcode project can now produce static gtest 96 | libraries in addition to a framework. 97 | * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, 98 | Symbian, gcc, and C++Builder. 99 | * Bug fixes and implementation clean-ups. 100 | 101 | Changes for 1.3.0: 102 | 103 | * New feature: death tests on Windows, Cygwin, and Mac. 104 | * New feature: ability to use Google Test assertions in other testing 105 | frameworks. 106 | * New feature: ability to run disabled test via 107 | --gtest_also_run_disabled_tests. 108 | * New feature: the --help flag for printing the usage. 109 | * New feature: access to Google Test flag values in user code. 110 | * New feature: a script that packs Google Test into one .h and one 111 | .cc file for easy deployment. 112 | * New feature: support for distributing test functions to multiple 113 | machines (requires support from the test runner). 114 | * Bug fixes and implementation clean-ups. 115 | 116 | Changes for 1.2.1: 117 | 118 | * Compatibility fixes for Linux IA-64 and IBM z/OS. 119 | * Added support for using Boost and other TR1 implementations. 120 | * Changes to the build scripts to support upcoming release of Google C++ 121 | Mocking Framework. 122 | * Added Makefile to the distribution package. 123 | * Improved build instructions in README. 124 | 125 | Changes for 1.2.0: 126 | 127 | * New feature: value-parameterized tests. 128 | * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) 129 | macros. 130 | * Changed the XML report format to match JUnit/Ant's. 131 | * Added tests to the Xcode project. 132 | * Added scons/SConscript for building with SCons. 133 | * Added src/gtest-all.cc for building Google Test from a single file. 134 | * Fixed compatibility with Solaris and z/OS. 135 | * Enabled running Python tests on systems with python 2.3 installed, 136 | e.g. Mac OS X 10.4. 137 | * Bug fixes. 138 | 139 | Changes for 1.1.0: 140 | 141 | * New feature: type-parameterized tests. 142 | * New feature: exception assertions. 143 | * New feature: printing elapsed time of tests. 144 | * Improved the robustness of death tests. 145 | * Added an Xcode project and samples. 146 | * Adjusted the output format on Windows to be understandable by Visual Studio. 147 | * Minor bug fixes. 148 | 149 | Changes for 1.0.1: 150 | 151 | * Added project files for Visual Studio 7.1. 152 | * Fixed issues with compiling on Mac OS X. 153 | * Fixed issues with compiling on Cygwin. 154 | 155 | Changes for 1.0.0: 156 | 157 | * Initial Open Source release of Google Test 158 | --------------------------------------------------------------------------------