techempower.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "src/reactor.h"
  2. #include "src/io_handle.h"
  3. #include "src/acceptor.h"
  4. #include "src/options.h"
  5. #include "src/poll_sync_opt.h"
  6. #include <string>
  7. #include <signal.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sys/time.h>
  12. #include <thread>
  13. reactor *conn_reactor = nullptr;
  14. const char httpheaders1[] = "HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nServer: goev\r\nContent-Type: text/plain\r\nDate: ";
  15. const char httpheaders2[] = "\r\nContent-Length: 13\r\n\r\nHello, World!";
  16. const int pcache_data_t = 1;
  17. class http : public io_handle {
  18. public:
  19. virtual bool on_open() {
  20. // add_ev_handler 尽量放在最后, (on_open 和o_read可能不在一个线程)
  21. if (conn_reactor->add_ev_handler(this, this->get_fd(), ev_handler::ev_read) != 0) {
  22. fprintf(stderr, "add new conn to poller fail! %s\n", strerror(errno));
  23. return false;
  24. }
  25. return true;
  26. }
  27. virtual bool on_read() {
  28. char *buf = nullptr;
  29. int ret = this->recv(buf);
  30. if (ret == 0) // closed
  31. return false;
  32. else if (ret < 0)
  33. return true;
  34. if (::strstr(buf, "\r\n\r\n") == nullptr) {
  35. // invliad msg
  36. return false;
  37. }
  38. int writen = 0;
  39. ::memcpy(buf, httpheaders1, sizeof(httpheaders1)-1);
  40. writen += sizeof(httpheaders1)-1;
  41. char *date = (char *)this->poll_cache_get(pcache_data_t);
  42. ret = ::strlen(date);
  43. ::memcpy(buf + writen, date, ret);
  44. writen += ret;
  45. ret = sizeof(httpheaders2)-1;
  46. ::memcpy(buf + writen, httpheaders2, ret);
  47. writen += ret;
  48. this->send(buf, writen);
  49. return true;
  50. }
  51. virtual void on_close() {
  52. this->destroy();
  53. }
  54. };
  55. ev_handler *gen_http() {
  56. return new http();
  57. }
  58. void release_dates(void *p) {
  59. delete[] (char *)p;
  60. }
  61. void sync_date(bool init) {
  62. struct timeval now;
  63. gettimeofday(&now, NULL);
  64. struct tm tmv;
  65. ::localtime_r(&(now.tv_sec), &tmv);
  66. char dates[32] = {0};
  67. ::strftime(dates, 32, "%a, %d %b %Y %H:%M:%S GMT", &tmv);
  68. void **args = new void *[conn_reactor->get_poller_num()];
  69. for (int i = 0; i < conn_reactor->get_poller_num(); ++i) {
  70. char *ds = new char[32]{0};
  71. ::strcpy(ds, dates);
  72. poll_sync_opt::sync_cache *arg = new poll_sync_opt::sync_cache();
  73. arg->id = pcache_data_t;
  74. arg->value = ds;
  75. arg->free_func = release_dates;
  76. args[i] = arg;
  77. }
  78. if (init)
  79. conn_reactor->init_poll_sync_opt(poll_sync_opt::sync_cache_t, args);
  80. else
  81. conn_reactor->poll_sync_opt(poll_sync_opt::sync_cache_t, args);
  82. }
  83. void sync_date_timing() {
  84. while (true) {
  85. std::this_thread::sleep_for(std::chrono::seconds(1));
  86. sync_date(false);
  87. }
  88. }
  89. int main (int argc, char *argv[]) {
  90. options opt;
  91. opt.set_cpu_affinity = true;
  92. if (argc > 1)
  93. opt.poller_num = atoi(argv[1]);
  94. signal(SIGPIPE ,SIG_IGN);
  95. conn_reactor = new reactor();
  96. if (conn_reactor->open(opt) != 0)
  97. ::exit(1);
  98. sync_date(true);
  99. std::thread thr(sync_date_timing);
  100. thr.detach();
  101. opt.reuse_addr = true;
  102. acceptor acc(conn_reactor, gen_http);
  103. if (acc.open(":8080", opt) != 0)
  104. ::exit(1);
  105. conn_reactor->run();
  106. }