diff --git a/modules/web/http_server_simple/http_server_simple.cpp b/modules/web/http_server_simple/http_server_simple.cpp index f668fb70a..8272cb307 100644 --- a/modules/web/http_server_simple/http_server_simple.cpp +++ b/modules/web/http_server_simple/http_server_simple.cpp @@ -305,21 +305,63 @@ void HTTPServerSimple::poll() { connection->peer = connection->tcp; connection->time = OS::get_singleton()->get_ticks_usec(); + _connections_lock.write_lock(); _connections.push_back(connection); + _connections_lock.write_unlock(); } - //TODO This should be done by worker threads (with a proper lock free queue) - for (int i = 0; i < _connections.size(); ++i) { - Ref c = _connections[i]; + /* + //THis will only work well in a worker thread + while (!_connections.empty()) { + _connections_lock.write_lock(); + Ref c = _connections.front()->get(); + _connections.pop_front(); + _connections_lock.write_unlock(); + + if (c->closed()) { + continue; + } + + c->update(); + + if (c->closed()) { + continue; + } + + _connections_lock.write_lock(); + _connections.push_back(c); + _connections_lock.write_unlock(); + } + */ + + //Single threaded ver + _connections_lock.write_lock(); + + List>::Element *e = _connections.front(); + + while (e) { + Ref c = e->get(); if (c->closed()) { - _connections.remove(i); - --i; + List>::Element *etmp = e->next(); + _connections.erase(e); + e = etmp; continue; } c->update(); + + if (c->closed()) { + List>::Element *etmp = e->next(); + _connections.erase(e); + e = etmp; + continue; + } + + e = e->next(); } + + _connections_lock.write_unlock(); } HTTPServerSimple::HTTPServerSimple() { @@ -341,11 +383,17 @@ HTTPServerSimple::~HTTPServerSimple() { } void HTTPServerSimple::_clear_clients() { - for (int i = 0; i < _connections.size(); ++i) { - _connections.write[i]->close(); + //stop worker threads first! + + _connections_lock.write_lock(); + + for (List>::Element *e = _connections.front(); e; e = e->next()) { + e->get()->close(); } _connections.clear(); + + _connections_lock.write_unlock(); } void HTTPServerSimple::_set_internal_certs(Ref p_crypto) { @@ -355,6 +403,7 @@ void HTTPServerSimple::_set_internal_certs(Ref p_crypto) { const String key_path = cache_path.plus_file("html5_server.key"); const String crt_path = cache_path.plus_file("html5_server.crt"); bool regen = !FileAccess::exists(key_path) || !FileAccess::exists(crt_path); + if (!regen) { key = Ref(CryptoKey::create()); cert = Ref(X509Certificate::create()); @@ -362,6 +411,7 @@ void HTTPServerSimple::_set_internal_certs(Ref p_crypto) { regen = true; } } + if (regen) { key = p_crypto->generate_rsa(2048); key->save(key_path); diff --git a/modules/web/http_server_simple/http_server_simple.h b/modules/web/http_server_simple/http_server_simple.h index 852eea0a0..08e09862d 100644 --- a/modules/web/http_server_simple/http_server_simple.h +++ b/modules/web/http_server_simple/http_server_simple.h @@ -34,6 +34,8 @@ #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/zip_io.h" +#include "core/list.h" +#include "core/os/rw_lock.h" #include "core/vector.h" #include "core/project_settings.h" @@ -103,8 +105,8 @@ private: Ref key; bool use_ssl = false; - //TODO add a lock free queue - Vector> _connections; + List> _connections; + RWLock _connections_lock; void _clear_clients(); void _set_internal_certs(Ref p_crypto); diff --git a/modules/web/http_server_simple/web_server_simple.cpp b/modules/web/http_server_simple/web_server_simple.cpp index 974bc30c4..57a0464f3 100644 --- a/modules/web/http_server_simple/web_server_simple.cpp +++ b/modules/web/http_server_simple/web_server_simple.cpp @@ -73,6 +73,10 @@ void WebServerSimple::_stop() { } WebServerSimple::WebServerSimple() { + _use_worker_threads = true; + _use_poll_thread = true; + _thread_count = 1; + server.instance(); server->_web_server = this; server_thread.start(_server_thread_poll, this); diff --git a/modules/web/http_server_simple/web_server_simple.h b/modules/web/http_server_simple/web_server_simple.h index e1c532b14..d4732e00b 100644 --- a/modules/web/http_server_simple/web_server_simple.h +++ b/modules/web/http_server_simple/web_server_simple.h @@ -60,6 +60,10 @@ protected: Mutex server_lock; Thread server_thread; + bool _use_poll_thread; + bool _use_worker_threads; + int _thread_count; + static void _server_thread_poll(void *data); };