diff --git a/VERSION b/VERSION index 50ffc5a..2165f8f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.3 +2.0.4 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0498104..3641a65 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +**2.0.4** +* Optimize Media Layer Proxy + **2.0.3** * Make "kill" Admin Command Print Death Message diff --git a/media-layer/proxy/src/GLESv1_CM.c b/media-layer/proxy/src/GLESv1_CM.c index 8c4245d..988ff08 100644 --- a/media-layer/proxy/src/GLESv1_CM.c +++ b/media-layer/proxy/src/GLESv1_CM.c @@ -328,6 +328,7 @@ CALL(24, glTexParameteri, void, (GLenum target, GLenum pname, GLint param)) { #endif } +// Get Size (In Memory) Of Specified Texture static int get_texture_size(GLsizei width, GLsizei height, GLenum format, GLenum type) { int multiplier; if (type == GL_UNSIGNED_BYTE) { diff --git a/media-layer/proxy/src/client/client.cpp b/media-layer/proxy/src/client/client.cpp index bae94a8..41eb73c 100644 --- a/media-layer/proxy/src/client/client.cpp +++ b/media-layer/proxy/src/client/client.cpp @@ -62,6 +62,7 @@ int main(int argc, char *argv[]) { // Send Connection Message write_string((char *) CONNECTED_MSG); + flush_write_cache(); // Loop int running = is_connection_open(); @@ -74,6 +75,9 @@ int main(int argc, char *argv[]) { if (!is_connection_open()) { // Exit running = 0; + } else { + // Flush Write Cache + flush_write_cache(); } } else { PROXY_ERR("Invalid Method ID: %i", (int) unique_id); diff --git a/media-layer/proxy/src/common/common.c b/media-layer/proxy/src/common/common.c index fb30ef1..3b3dd67 100644 --- a/media-layer/proxy/src/common/common.c +++ b/media-layer/proxy/src/common/common.c @@ -15,9 +15,13 @@ } \ } void safe_read(void *buf, size_t len) { + // Check Data if (buf == NULL) { PROXY_ERR("%s", "Attempting To Read Into NULL Buffer"); } + // Flush Write Cache + flush_write_cache(); + // Read size_t to_read = len; while (to_read > 0) { CHECK_CONNECTION(); @@ -29,19 +33,58 @@ void safe_read(void *buf, size_t len) { } } // Buffer Writes +static void *_write_cache = NULL; +__attribute__((destructor)) static void _free_write_cache() { + if (_write_cache != NULL) { + free(_write_cache); + } +} +static size_t _write_cache_size = 0; +static size_t _write_cache_position = 0; void safe_write(void *buf, size_t len) { + // Check Data if (buf == NULL) { PROXY_ERR("%s", "Attempting To Send NULL Data"); } - size_t to_write = len; + // Expand Write Cache If Needed + size_t needed_size = _write_cache_position + len; + if (_write_cache == NULL) { + _write_cache_size = needed_size; + _write_cache = malloc(_write_cache_size); + } else if (needed_size > _write_cache_size) { + _write_cache_size = needed_size; + _write_cache = realloc(_write_cache, _write_cache_size); + } + ALLOC_CHECK(_write_cache); + // Copy Data + memcpy(_write_cache + _write_cache_position, buf, len); + // Advance Position + _write_cache_position += len; +} +// Flush Write Cache +void flush_write_cache() { + // Check Connection + if (!is_connection_open()) { + // Connection Closed + return; + } + // Check Cache + if (_write_cache == NULL || _write_cache_position < 1) { + // Nothing To Write + return; + } + // Write + size_t to_write = _write_cache_position; while (to_write > 0) { CHECK_CONNECTION(); - ssize_t x = write(get_connection_write(), buf + (len - to_write), to_write); + ssize_t x = write(get_connection_write(), _write_cache + (_write_cache_position - to_write), to_write); if (x == -1 && errno != EINTR) { PROXY_ERR("Failed Writing Data To Connection: %s", strerror(errno)); } to_write -= x; } + // Reset + _write_cache_position = 0; } // Read/Write 32-Bit Integers @@ -107,6 +150,9 @@ void write_string(char *str) { // Close Connection void close_connection() { + // Flush Write Cache + flush_write_cache(); + // Close int state_changed = 0; if (get_connection_read() != -1) { close(get_connection_read()); diff --git a/media-layer/proxy/src/common/common.h b/media-layer/proxy/src/common/common.h index 64bfd6c..31ffab0 100644 --- a/media-layer/proxy/src/common/common.h +++ b/media-layer/proxy/src/common/common.h @@ -28,6 +28,7 @@ extern "C" { // Safely Send/Receive Data From The Connection __attribute__((visibility("internal"))) void safe_read(void *buf, size_t len); __attribute__((visibility("internal"))) void safe_write(void *buf, size_t len); +__attribute__((visibility("internal"))) void flush_write_cache(); // Read/Write 32-Bit Integers __attribute__((visibility("internal"))) uint32_t read_int(); diff --git a/media-layer/proxy/src/media-layer-core.c b/media-layer/proxy/src/media-layer-core.c index 5aa5080..005ae54 100644 --- a/media-layer/proxy/src/media-layer-core.c +++ b/media-layer/proxy/src/media-layer-core.c @@ -259,7 +259,7 @@ CALL(5, SDL_WM_GrabInput, SDL_GrabMode, (SDL_GrabMode mode)) { #endif } -CALL(6,SDL_ShowCursor, int, (int32_t toggle)) { +CALL(6, SDL_ShowCursor, int, (int32_t toggle)) { #if defined(MEDIA_LAYER_PROXY_SERVER) // Lock Proxy start_proxy_call(); diff --git a/media-layer/proxy/src/server/server.cpp b/media-layer/proxy/src/server/server.cpp index 625093f..0e3bbdf 100644 --- a/media-layer/proxy/src/server/server.cpp +++ b/media-layer/proxy/src/server/server.cpp @@ -147,8 +147,22 @@ static std::unordered_map &get_unique_ids() { void _assign_unique_id(const char *name, unsigned char id) { get_unique_ids()[name] = id; } -__attribute__((const)) static unsigned char get_unique_id(const char *name) { - return get_unique_ids()[name]; // Assume ID Exists +// Only Compare Strings The First Time, Then Cache C String Addresses +static std::unordered_map &get_unique_ids_cache() { + static std::unordered_map unique_ids; + return unique_ids; +} +static unsigned char get_unique_id(const char *name) { + // Check If C String Is Cached + if (get_unique_ids_cache().find(name) != get_unique_ids_cache().end()) { + // Use Cache + return get_unique_ids_cache()[name]; + } else { + // Compare Strings + unsigned char id = get_unique_ids()[name]; // Assume ID Exists + get_unique_ids_cache()[name] = id; + return id; + } } // The Proxy Is Single-Threaded @@ -159,6 +173,8 @@ void _start_proxy_call(const char *call_name) { write_byte(get_unique_id(call_name)); } void end_proxy_call() { + // Flush Write Cache + flush_write_cache(); // Release Proxy pthread_mutex_unlock(&proxy_mutex); }