You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cpp 1.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /***********************************************
  2. File Name: main.cpp
  3. Author: Abby Cin
  4. Mail: abbytsing@gmail.com
  5. Created Time: 10/24/20 2:45 PM
  6. ***********************************************/
  7. #include "aux.h"
  8. #include "context.h"
  9. #include "peer.h"
  10. #include "acceptor.h"
  11. struct task
  12. {
  13. };
  14. template<typename... Args>
  15. struct std::coroutine_traits<task, Args...>
  16. {
  17. struct promise_type
  18. {
  19. task get_return_object() { return {}; }
  20. suspend_never initial_suspend() { return {}; }
  21. suspend_never final_suspend() { return {}; }
  22. void return_void(){};
  23. void unhandled_exception() { std::terminate(); }
  24. };
  25. };
  26. task session(peer&& tmp)
  27. {
  28. peer client{std::move(tmp)};
  29. char data[128]{};
  30. for(;;)
  31. {
  32. auto n = co_await client.read_some(data, sizeof(data));
  33. if(n < 1)
  34. {
  35. break;
  36. }
  37. int sent = 0;
  38. while(sent < n)
  39. {
  40. auto x = co_await client.write_some(data + sent, n - sent);
  41. if(x < 0)
  42. {
  43. sent = x;
  44. break;
  45. }
  46. sent += x;
  47. }
  48. if(sent < 0)
  49. {
  50. break;
  51. }
  52. }
  53. }
  54. task spawn(context& ctx, resolver& rr)
  55. {
  56. acceptor a{ctx, rr};
  57. if(a.listen() < 0)
  58. {
  59. ctx.stop();
  60. co_return;
  61. }
  62. for(;;)
  63. {
  64. session(co_await a.accept());
  65. if(!ctx.running())
  66. {
  67. break;
  68. }
  69. }
  70. }
  71. context* gctx = nullptr;
  72. void handler(int) { gctx->stop(); }
  73. int main()
  74. {
  75. context ctx{};
  76. auto addr = resolver::from_str("127.0.0.1:8889");
  77. spawn(ctx, addr);
  78. ::signal(SIGINT, handler);
  79. ::signal(SIGTERM, handler);
  80. gctx = &ctx;
  81. ctx.run();
  82. }