summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-11-16 02:49:22 +0000
committerDavid Robillard <d@drobilla.net>2008-11-16 02:49:22 +0000
commit24d998447070dbfef3eaf7762dce7e97c3903801 (patch)
tree0feffd6ca3c4459e0a7ff6fad9cf48b7816f2cd7 /src/shared
parentfb6471ac9d5daefd3655bc19532a6028b5f0ead4 (diff)
downloadingen-24d998447070dbfef3eaf7762dce7e97c3903801.tar.gz
ingen-24d998447070dbfef3eaf7762dce7e97c3903801.tar.bz2
ingen-24d998447070dbfef3eaf7762dce7e97c3903801.zip
TCP notification stream support (not fully implemented yet, but transport stuff is working).
Support multiple event sources in the engine. Clean up HTTP/TCP stuff. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1721 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/HTTPSender.cpp111
-rw-r--r--src/shared/HTTPSender.hpp21
2 files changed, 110 insertions, 22 deletions
diff --git a/src/shared/HTTPSender.cpp b/src/shared/HTTPSender.cpp
index 20135b2a..7f760786 100644
--- a/src/shared/HTTPSender.cpp
+++ b/src/shared/HTTPSender.cpp
@@ -20,6 +20,12 @@
#include <iostream>
#include <unistd.h>
#include <stdarg.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include <cstring>
using namespace std;
@@ -27,53 +33,126 @@ namespace Ingen {
namespace Shared {
-HTTPSender::HTTPSender(SoupServer* server, SoupMessage* msg)
- : _server(server)
- , _msg(msg)
+HTTPSender::HTTPSender()
+ : _listen_port(-1)
+ , _listen_sock(-1)
+ , _client_sock(-1)
+ , _send_state(Immediate)
{
- soup_message_headers_set_encoding(msg->response_headers, SOUP_ENCODING_CHUNKED);
- cout << "Hello?" << endl;
- send_chunk("hello");
+ Thread::set_name("HTTP Sender");
+
+ struct sockaddr_in addr;
+
+ // Create listen address
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ // Create listen socket
+ if ((_listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
+ fprintf(stderr, "Error creating listening socket (%s)\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ // Bind our socket addresss to the listening socket
+ if (bind(_listen_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ fprintf(stderr, "Error calling bind (%s)\n", strerror(errno));
+ _listen_sock = -1;
+ }
+
+ // Find port number
+ socklen_t length = sizeof(addr);
+ if (getsockname(_listen_sock, (struct sockaddr*)&addr, &length) == -1) {
+ fprintf(stderr, "Error calling getsockname (%s)\n", strerror(errno));
+ _listen_sock = -1;
+ return;
+ }
+
+ if (listen(_listen_sock, 1) < 0 ) {
+ cerr << "Error calling listen: %s" << strerror(errno) << endl;
+ _listen_sock = -1;
+ return;
+ }
+
+ _listen_port = ntohs(addr.sin_port);
+ cout << "Opening event stream on TCP port " << _listen_port << endl;
+ start();
}
HTTPSender::~HTTPSender()
{
- cout << "HTTP SENDER EXIT" << endl;
- soup_message_body_complete(_msg->response_body);
- soup_server_unpause_message(_server, _msg);
+ stop();
+ if (_listen_sock != -1)
+ close(_listen_sock);
+ if (_client_sock != -1)
+ close(_client_sock);
+}
+
+void
+HTTPSender::_run()
+{
+ if (_listen_sock == -1) {
+ cerr << "Unable to open socket, exiting sender thread" << endl;
+ return;
+ }
+
+ // Accept connection
+ if ((_client_sock = accept(_listen_sock, NULL, NULL) ) < 0) {
+ cerr << "Error calling accept: " << strerror(errno) << endl;
+ return;
+ }
+
+ // Hold connection open and write when signalled
+ while (true) {
+ _mutex.lock();
+ _signal.wait(_mutex);
+
+ write(_client_sock, _transfer.c_str(), _transfer.length());
+ write(_client_sock, "\n\n", 2);
+
+ _mutex.unlock();
+ }
+
+ close(_listen_sock);
+ _listen_sock = -1;
}
void
HTTPSender::bundle_begin()
{
+ _mutex.lock();
_send_state = SendingBundle;
+ _transfer = "";
+ _mutex.unlock();
}
void
HTTPSender::bundle_end()
{
+ _mutex.lock();
assert(_send_state == SendingBundle);
- soup_message_body_append(_msg->response_body,
- SOUP_MEMORY_TEMPORARY, _transfer.c_str(), _transfer.length());
- soup_server_unpause_message(_server, _msg);
- _transfer = "";
+ _signal.broadcast();
_send_state = Immediate;
+ _mutex.unlock();
}
void
HTTPSender::send_chunk(const std::string& buf)
{
+ _mutex.lock();
+
if (_send_state == Immediate) {
- soup_message_body_append(_msg->response_body,
- SOUP_MEMORY_TEMPORARY, buf.c_str(), buf.length());
- soup_server_unpause_message(_server, _msg);
+ _transfer = "";
+ _signal.broadcast();
} else {
_transfer.append(buf);
}
+
+ _mutex.unlock();
}
diff --git a/src/shared/HTTPSender.hpp b/src/shared/HTTPSender.hpp
index 1025c071..1077b76d 100644
--- a/src/shared/HTTPSender.hpp
+++ b/src/shared/HTTPSender.hpp
@@ -20,14 +20,15 @@
#include <stdint.h>
#include <string>
-#include <libsoup/soup.h>
+#include <glibmm/thread.h>
+#include "raul/Thread.hpp"
namespace Ingen {
namespace Shared {
-class HTTPSender {
+class HTTPSender : public Raul::Thread {
public:
- HTTPSender(SoupServer* server, SoupMessage* msg);
+ HTTPSender();
virtual ~HTTPSender();
// Message bundling
@@ -38,13 +39,21 @@ public:
void transfer_begin() { bundle_begin(); }
void transfer_end() { bundle_end(); }
+ int listen_port() const { return _listen_port; }
+
protected:
- void send_chunk(const std::string& buf);
+ void _run();
+ void send_chunk(const std::string& buf);
+
enum SendState { Immediate, SendingBundle };
- SoupServer* _server;
- SoupMessage* _msg;
+ Glib::Mutex _mutex;
+ Glib::Cond _signal;
+
+ int _listen_port;
+ int _listen_sock;
+ int _client_sock;
SendState _send_state;
std::string _transfer;
};