lazy loading + convert queue's char[] to pointer

This commit is contained in:
Adonis Najimi 2018-05-14 22:23:52 +02:00
commit 34183ad1a6
3 changed files with 37 additions and 38 deletions

View file

@ -1,9 +1,9 @@
#include "apkinstaller.h" #include "installer.h"
#include <string.h>
#include "lockutil.h" #include "lockutil.h"
#include "log.h" #include "log.h"
#include "command.h" #include "command.h"
#include <string.h>
// NOTE(adopi) this can be more generic: // NOTE(adopi) this can be more generic:
@ -33,21 +33,23 @@ SDL_bool apk_queue_push(struct apk_queue *queue, const char *apk) {
return SDL_FALSE; return SDL_FALSE;
} }
strncpy(queue->data[queue->head], apk, MAX_FILENAME_SIZE); queue->data[queue->head] = SDL_strdup(apk);
// strncpy(queue->data[queue->head], apk, MAX_FILENAME_SIZE);
queue->head = (queue->head + 1) % APK_QUEUE_SIZE; queue->head = (queue->head + 1) % APK_QUEUE_SIZE;
return SDL_TRUE; return SDL_TRUE;
} }
SDL_bool apk_queue_take(struct apk_queue *queue, char *apk) { SDL_bool apk_queue_take(struct apk_queue *queue, char **apk) {
if (apk_queue_is_empty(queue)) { if (apk_queue_is_empty(queue)) {
return SDL_FALSE; return SDL_FALSE;
} }
strncpy(apk, queue->data[queue->tail], MAX_FILENAME_SIZE); *apk = SDL_strdup(queue->data[queue->tail]);
// strncpy(apk, queue->data[queue->tail], MAX_FILENAME_SIZE);
queue->tail = (queue->tail + 1) % APK_QUEUE_SIZE; queue->tail = (queue->tail + 1) % APK_QUEUE_SIZE;
return SDL_TRUE; return SDL_TRUE;
} }
SDL_bool installer_init(struct installer *installer, const char* serial) { SDL_bool installer_init(struct installer *installer, const char *serial) {
if (!apk_queue_init(&installer->queue)) { if (!apk_queue_init(&installer->queue)) {
return SDL_FALSE; return SDL_FALSE;
@ -67,7 +69,8 @@ SDL_bool installer_init(struct installer *installer, const char* serial) {
installer->serial = SDL_strdup(serial); installer->serial = SDL_strdup(serial);
} }
installer->initialized = SDL_TRUE; // lazy initialization
installer->initialized = SDL_FALSE;
installer->stopped = SDL_FALSE; installer->stopped = SDL_FALSE;
return SDL_TRUE; return SDL_TRUE;
@ -83,8 +86,17 @@ void installer_destroy(struct installer *installer) {
installer->current_process = PROCESS_NONE; installer->current_process = PROCESS_NONE;
} }
SDL_bool installer_push_apk(struct installer *installer, const char* apk) { SDL_bool installer_install_apk(struct installer *installer, const char *apk) {
SDL_bool res; SDL_bool res;
// start installer if it's used for the first time
if (!installer->initialized) {
if (!installer_start(installer)) {
return SDL_FALSE;
}
installer->initialized = SDL_TRUE;
}
mutex_lock(installer->mutex); mutex_lock(installer->mutex);
SDL_bool was_empty = apk_queue_is_empty(&installer->queue); SDL_bool was_empty = apk_queue_is_empty(&installer->queue);
res = apk_queue_push(&installer->queue, apk); res = apk_queue_push(&installer->queue, apk);
@ -95,7 +107,7 @@ SDL_bool installer_push_apk(struct installer *installer, const char* apk) {
return res; return res;
} }
static SDL_bool process_install(struct installer *installer, const char* filename) { static SDL_bool process_install(struct installer *installer, const char *filename) {
LOGI("%s will be installed",filename); LOGI("%s will be installed",filename);
process_t process = adb_install(installer->serial, filename); process_t process = adb_install(installer->serial, filename);
installer->current_process = process; installer->current_process = process;
@ -105,7 +117,7 @@ static SDL_bool process_install(struct installer *installer, const char* filenam
static int run_installer(void *data) { static int run_installer(void *data) {
struct installer *installer = data; struct installer *installer = data;
char current_apk[MAX_FILENAME_SIZE]; char *current_apk;
mutex_lock(installer->mutex); mutex_lock(installer->mutex);
for (;;) { for (;;) {
while (!installer->stopped && apk_queue_is_empty(&installer->queue)) { while (!installer->stopped && apk_queue_is_empty(&installer->queue)) {
@ -115,7 +127,7 @@ static int run_installer(void *data) {
// stop immediately, do not process further events // stop immediately, do not process further events
break; break;
} }
while (apk_queue_take(&installer->queue, current_apk)) { while (apk_queue_take(&installer->queue, &current_apk)) {
SDL_bool ok = process_install(installer,current_apk); SDL_bool ok = process_install(installer,current_apk);
if (!ok) { if (!ok) {
LOGD("Error during installation"); LOGD("Error during installation");

View file

@ -1,27 +1,23 @@
#ifndef APK_INSTALLER_H #ifndef APK_INSTALLER_H
#define APK_INSTALLER_H #define APK_INSTALLER_H
#define APK_QUEUE_SIZE 16
#define MAX_FILENAME_SIZE 1024
#include "apkinstaller.h"
#include <SDL2/SDL_mutex.h> #include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_stdinc.h> #include <SDL2/SDL_stdinc.h>
#include <SDL2/SDL_thread.h> #include <SDL2/SDL_thread.h>
#include "command.h" #include "command.h"
#define APK_QUEUE_SIZE 16
// NOTE(AdoPi) apk_queue and control_event can use a generic queue // NOTE(AdoPi) apk_queue and control_event can use a generic queue
struct apk_queue { struct apk_queue {
char data[APK_QUEUE_SIZE][MAX_FILENAME_SIZE]; char *data[APK_QUEUE_SIZE];
int tail; int tail;
int head; int head;
}; };
struct installer { struct installer {
const char* serial; const char *serial;
SDL_Thread *thread; SDL_Thread *thread;
SDL_mutex *mutex; SDL_mutex *mutex;
SDL_cond *event_cond; SDL_cond *event_cond;
@ -42,7 +38,7 @@ struct installer {
} }
SDL_bool installer_init(struct installer *installer, const char* serial); SDL_bool installer_init(struct installer *installer, const char *serial);
void installer_destroy(struct installer *installer); void installer_destroy(struct installer *installer);
SDL_bool installer_start(struct installer *installer); SDL_bool installer_start(struct installer *installer);
@ -50,6 +46,6 @@ void installer_stop(struct installer *installer);
void installer_join(struct installer *installer); void installer_join(struct installer *installer);
// install an apk // install an apk
SDL_bool installer_push_apk(struct installer *installer, const char* filename); SDL_bool installer_install_apk(struct installer *installer, const char *filename);
#endif #endif

View file

@ -22,7 +22,7 @@
#include "screen.h" #include "screen.h"
#include "server.h" #include "server.h"
#include "tinyxpm.h" #include "tinyxpm.h"
#include "apkinstaller.h" #include "installer.h"
static struct server server = SERVER_INITIALIZER; static struct server server = SERVER_INITIALIZER;
static struct screen screen = SCREEN_INITIALIZER; static struct screen screen = SCREEN_INITIALIZER;
@ -105,16 +105,7 @@ static void event_loop(void) {
input_manager_process_mouse_button(&input_manager, &event.button); input_manager_process_mouse_button(&input_manager, &event.button);
break; break;
case SDL_DROPFILE: case SDL_DROPFILE:
installer_install_apk(&installer, event.drop.file);
if (!installer.initialized) {
SDL_bool init_ok = installer_init(&installer, server.serial);
if (init_ok && installer_start(&installer)) {
goto push;
}
installer_destroy(&installer);
}
push:
installer_push_apk(&installer, event.drop.file);
break; break;
} }
} }
@ -161,6 +152,9 @@ SDL_bool scrcpy(const char *serial, Uint16 local_port, Uint16 max_size, Uint32 b
goto finally_destroy_server; goto finally_destroy_server;
} }
// TODO(adopi) check failure
installer_init(&installer,server.serial);
decoder_init(&decoder, &frames, device_socket); decoder_init(&decoder, &frames, device_socket);
// now we consumed the header values, the socket receives the video stream // now we consumed the header values, the socket receives the video stream
@ -181,7 +175,6 @@ SDL_bool scrcpy(const char *serial, Uint16 local_port, Uint16 max_size, Uint32 b
goto finally_destroy_controller; goto finally_destroy_controller;
} }
if (!screen_init_rendering(&screen, device_name, frame_size)) { if (!screen_init_rendering(&screen, device_name, frame_size)) {
ret = SDL_FALSE; ret = SDL_FALSE;
goto finally_stop_and_join_controller; goto finally_stop_and_join_controller;
@ -199,11 +192,9 @@ finally_destroy_controller:
finally_stop_decoder: finally_stop_decoder:
decoder_stop(&decoder); decoder_stop(&decoder);
// stop installer // stop installer
if (installer.initialized) { installer_stop(&installer);
installer_stop(&installer); installer_join(&installer);
installer_join(&installer); installer_destroy(&installer);
installer_destroy(&installer);
}
// stop the server before decoder_join() to wake up the decoder // stop the server before decoder_join() to wake up the decoder
server_stop(&server); server_stop(&server);
decoder_join(&decoder); decoder_join(&decoder);