summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/Socket.h3
-rw-r--r--src/Socket.cc46
2 files changed, 23 insertions, 26 deletions
diff --git a/includes/Socket.h b/includes/Socket.h
index 2a6a95d..7972cb5 100644
--- a/includes/Socket.h
+++ b/includes/Socket.h
@@ -10,6 +10,7 @@
#include <Handle.h>
#include <TaskMan.h>
#include <Task.h>
+#include <StacklessTask.h>
#include <Printer.h>
namespace Balau {
@@ -61,7 +62,7 @@ class Socket : public Handle {
DNSRequest * m_req = NULL;
};
-class ListenerBase : public Task {
+class ListenerBase : public StacklessTask {
public:
virtual void Do();
void stop();
diff --git a/src/Socket.cc b/src/Socket.cc
index a28b4c1..8989a72 100644
--- a/src/Socket.cc
+++ b/src/Socket.cc
@@ -201,24 +201,25 @@ namespace {
class AsyncOpResolv : public Balau::AsyncOperation {
public:
AsyncOpResolv(const char * name, const char * service, struct addrinfo * hints, Balau::DNSRequest * request)
- : m_name(name)
- , m_service(service)
- , m_hints(hints)
+ : m_name(name ? ::strdup(name) : NULL)
+ , m_service(service ? ::strdup(service) : NULL)
+ , m_hints(*hints)
, m_request(request)
{ }
+ virtual ~AsyncOpResolv() { free(m_name); free(m_service); }
virtual bool needsMainQueue() { return false; }
virtual bool needsFinishWorker() { return true; }
virtual void run() {
- m_request->error = getaddrinfo(m_name, m_service, m_hints, &m_request->res);
+ m_request->error = getaddrinfo(m_name, m_service, &m_hints, &m_request->res);
}
virtual void done() {
m_request->evt.doSignal();
delete this;
}
private:
- const char * m_name;
- const char * m_service;
- struct addrinfo * m_hints;
+ char * m_name;
+ char * m_service;
+ struct addrinfo m_hints;
Balau::DNSRequest * m_request;
};
@@ -629,25 +630,20 @@ void Balau::ListenerBase::stop() {
}
void Balau::ListenerBase::Do() {
- bool r = m_listener->setLocal(m_local.to_charp(), m_port);
- EAssert(r, "Couldn't set the local IP/port to listen to");
- r = m_listener->listen();
- EAssert(r, "Couldn't listen on the given IP/port");
- setName();
- setOkayToEAgain(true);
- waitFor(&m_evt);
+ bool r;
+ IO<Socket> io;
while (!m_stop) {
- IO<Socket> io;
- try {
- io = m_listener->accept();
- }
- catch (EAgain) {
- Printer::elog(E_SOCKET, "Listener task at %p (%s) got an EAgain - stop = %s", this, m_name.to_charp(), m_stop ? "true" : "false");
- if (m_stop)
- return;
- yield();
- continue;
- }
+ StacklessBegin();
+ StacklessOperation(r = m_listener->setLocal(m_local.to_charp(), m_port));
+ EAssert(r, "Couldn't set the local IP/port to listen to");
+ r = m_listener->listen();
+ EAssert(r, "Couldn't listen on the given IP/port");
+ setName();
+ waitFor(&m_evt);
+ StacklessOperationOrCond(io = m_listener->accept(), m_stop);
+ if (m_stop)
+ return;
factory(io, m_opaque);
+ StacklessEnd();
}
}