libtasks Documentation  1.6
acceptor.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014 ADTECH GmbH
3  * Licensed under MIT (https://github.com/adtechlabs/libtasks/blob/master/COPYING)
4  *
5  * Author: Andreas Pohl
6  */
7 
8 #ifndef _TASKS_ACCEPTOR_H_
9 #define _TASKS_ACCEPTOR_H_
10 
11 #include <cassert>
12 #include <vector>
13 
14 #include <tasks/net_io_task.h>
15 #include <tasks/dispatcher.h>
16 #include <tasks/logging.h>
17 
18 namespace tasks {
19 namespace net {
20 
25 template <class T>
26 class acceptor : public net_io_task {
27  public:
31  acceptor(int port) : net_io_task(EV_READ) {
32  // Create a non-blocking master socket.
33  tdbg("acceptor(" << this << "): listening on port " << port << std::endl);
34  try {
35  socket().listen(port);
36  } catch (socket_exception& e) {
37  terr("acceptor(" << this << "): " << e.what() << std::endl);
38  assert(false);
39  }
40  }
41 
45  acceptor(std::string path) : net_io_task(EV_READ) {
46  // Create a non-blocking master socket.
47  tdbg("acceptor(" << this << "): listening on unix:" << path << std::endl);
48  try {
49  socket().listen(path);
50  } catch (socket_exception& e) {
51  terr("acceptor(" << this << "): " << e.what() << std::endl);
52  assert(false);
53  }
54  }
55 
57 
59  bool handle_event(worker* worker, int /* revents */) {
60  try {
61  net::socket client = socket().accept();
62  tdbg("acceptor(" << this << "): new client fd " << client.fd() << std::endl);
63  T* task = new T(client);
64  // Note: Calling net_io_tasks::add_task will add the client fd to the event loop from the context of the
65  // current worker thread. If you are using multi loop mode this meams a client fd will always be added to
66  // the same event loop as the server socket and won't be handled by other threads. If you run only one
67  // acceptor you will effectively running single threaded. But this can be very usefull if you are running
68  // one acceptor per worker.
69  // If you need to distribute client fd's accross your workers you should implement you own acceptor and
70  // use
71  //
72  // dispatcher::instance()->add_task(task);
73  //
74  // instead.
75  add_task(worker, task);
76  } catch (socket_exception& e) {
77  terr("acceptor(" << this << "): " << e.what() << std::endl);
78  assert(false);
79  }
80  return true;
81  }
82 };
83 
84 } // net
85 } // tasks
86 
87 #endif // _TASKS_ACCEPTOR_H_
The base class for any task.
Definition: task.h:19
static void add_task(net_io_task *task)
Definition: net_io_task.cpp:40
bool handle_event(worker *worker, int)
Definition: acceptor.h:59
The net_io_task implements the base for socket based network tasks.
Definition: net_io_task.h:21
#define terr(m)
Definition: logging.h:57
#define tdbg(m)
Definition: logging.h:54
int fd() const
Definition: io_base.h:22
The socket class.
Definition: socket.h:35
Tasks execption class.
socket accept()
Accept new client connections.
Definition: socket.cpp:136
void shutdown()
Call shutdown on the fd.
Definition: socket.cpp:218
net::socket & socket()
Provide access to the underlying socket object.
Definition: net_io_task.h:35
const char * what() const noexcept
Return the error message.
acceptor(int port)
Definition: acceptor.h:31
void listen(std::string path, int queue_size=128)
Definition: socket.cpp:36
acceptor(std::string path)
Definition: acceptor.h:45