#include <Ecore_Evas.h> /* fb.h */
#include <aul.h>
#include <Ecore.h>
+#include <ail.h>
#include <packet.h>
#include <com-core_packet.h>
#include <livebox-errno.h>
#include <livebox-service.h>
+#include "critical_log.h"
#include "conf.h"
#include "debug.h"
#include "server.h"
return ECORE_CALLBACK_CANCEL;
}
+/*
+static inline void clear_pd_monitor(struct inst_info *inst)
+{
+ Ecore_Timer *pd_monitor;
+
+ pd_monitor = instance_del_data(inst, "pd,open,monitor");
+ if (pd_monitor) {
+ DbgPrint("Clear pd,open,monitor\n");
+ (void)instance_client_pd_created(inst, LB_STATUS_SUCCESS);
+ ecore_timer_del(pd_monitor);
+ (void)instance_unref(inst);
+ return;
+ }
+
+ pd_monitor = instance_del_data(inst, "pd,close,monitor");
+ if (pd_monitor) {
+ DbgPrint("Clear pd,close,monitor\n");
+ (void)instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS);
+ ecore_timer_del(pd_monitor);
+ (void)instance_unref(inst);
+ return;
+ }
+
+ pd_monitor = instance_del_data(inst, "pd,resize,monitor");
+ if (pd_monitor) {
+ DbgPrint("Clear pd,resize,monitor\n");
+ (void)instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS);
+ ecore_timer_del(pd_monitor);
+ (void)instance_unref(inst);
+ return;
+ }
+}
+*/
+
static struct packet *client_delete(pid_t pid, int handle, const struct packet *packet) /* pid, pkgname, filename, ret */
{
struct client_node *client;
* So We have to make a delay to send a deleted event.
*/
+ DbgPrint("Client has PD\n");
item->client = client_ref(client);
item->inst = instance_ref(inst);
}
}
} else {
+ DbgPrint("Client has no permission\n");
ret = LB_STATUS_ERROR_PERMISSION;
}
} else {
+ DbgPrint("Ok. destroy instance\n");
+ //clear_pd_monitor(inst);
ret = instance_destroy(inst);
}
int width;
int height;
char *lb_pkgname;
+ char *mainappid;
client = client_find_by_pid(pid);
if (!client) {
goto out;
}
+ mainappid = livebox_service_mainappid(lb_pkgname);
+ if (!package_is_enabled(mainappid)) {
+ DbgFree(mainappid);
+ DbgFree(lb_pkgname);
+ ret = LB_STATUS_ERROR_DISABLED;
+ goto out;
+ }
+ DbgFree(mainappid);
+
info = package_find(lb_pkgname);
if (!info)
info = package_create(lb_pkgname);
static Eina_Bool lazy_pd_created_cb(void *data)
{
- (void)instance_del_data(data, "lazy,pd,open");
-
- /*!
- * After unref instance first,
- * if the instance is not destroyed, try to notify the created PD event to the client.
- */
- if (instance_unref(data)) {
- int ret;
- ret = instance_client_pd_created(data, LB_STATUS_SUCCESS);
- DbgPrint("Send PD Create event (%d)\n", ret);
+ if (!!instance_del_data(data, "lazy,pd,open")) {
+ /*!
+ * After unref instance first,
+ * if the instance is not destroyed, try to notify the created PD event to the client.
+ */
+ if (instance_unref(data)) {
+ int ret;
+ ret = instance_client_pd_created(data, LB_STATUS_SUCCESS);
+ DbgPrint("Send PD Create event (%d)\n", ret);
+ }
}
return ECORE_CALLBACK_CANCEL;
static Eina_Bool lazy_pd_destroyed_cb(void *data)
{
- (void)instance_del_data(data, "lazy,pd,close");
-
- if (instance_unref(data)) {
- DbgPrint("Send PD Destroy event\n");
- instance_client_pd_destroyed(data, LB_STATUS_SUCCESS);
+ if (!!instance_del_data(data, "lazy,pd,close")) {
+ if (instance_unref(data)) {
+ int ret;
+ ret = instance_client_pd_destroyed(data, LB_STATUS_SUCCESS);
+ DbgPrint("Send PD Destroy event (%d)\n", ret);
+ }
}
return ECORE_CALLBACK_CANCEL;
ret = instance_client_pd_destroyed(data, LB_STATUS_ERROR_TIMEOUT);
(void)instance_del_data(data, "pd,close,monitor");
(void)instance_unref(data);
- ErrPrint("PD Close request it not processed in %lf seconds\n", PD_REQUEST_TIMEOUT);
+ ErrPrint("PD Close request is not processed in %lf seconds (%d)\n", PD_REQUEST_TIMEOUT, ret);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool pd_resize_monitor_cb(void *data)
+{
+ int ret;
+
+ ret = instance_client_pd_destroyed(data, LB_STATUS_ERROR_TIMEOUT);
+ (void)instance_del_data(data, "pd,resize,monitor");
+ (void)instance_unref(data);
+ ErrPrint("PD Resize request is not processed in %lf seconds (%d)\n", PD_REQUEST_TIMEOUT, ret);
return ECORE_CALLBACK_CANCEL;
}
if (ret != LB_STATUS_SUCCESS)
goto out;
- if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE)
+ if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) {
ret = LB_STATUS_ERROR_NO_SPACE;
- else if (package_pd_type(instance_package(inst)) == PD_TYPE_BUFFER) {
+ } else if (package_pd_type(instance_package(inst)) == PD_TYPE_BUFFER) {
+ lazy_pd_destroyed_cb(inst);
+
+ if (instance_get_data(inst, "pd,open,monitor")) {
+ DbgPrint("PD Open request is already processed\n");
+ ret = LB_STATUS_ERROR_ALREADY;
+ goto out;
+ }
+
+ if (instance_get_data(inst, "pd,close,monitor")) {
+ DbgPrint("PD Close request is already in process\n");
+ ret = LB_STATUS_ERROR_BUSY;
+ goto out;
+ }
+
+ if (instance_get_data(inst, "pd,resize,monitor")) {
+ DbgPrint("PD resize request is already in process\n");
+ ret = LB_STATUS_ERROR_BUSY;
+ goto out;
+ }
+
instance_slave_set_pd_pos(inst, x, y);
/*!
* \note
} else if (package_pd_type(instance_package(inst)) == PD_TYPE_SCRIPT) {
int ix;
int iy;
+
+ lazy_pd_destroyed_cb(inst);
+
/*!
* \note
* ret value should be cared but in this case,
*/
if (ret == LB_STATUS_SUCCESS) {
Ecore_Timer *timer;
+
/*!
* \note
* But the created event has to be send afte return
int ret;
struct inst_info *inst;
const struct pkg_info *pkg;
+ Ecore_Timer *pd_monitor;
client = client_find_by_pid(pid);
if (!client) {
goto out;
if (package_pd_type(pkg) == PD_TYPE_BUFFER) {
- Ecore_Timer *pd_monitor;
+ int resize_aborted = 0;
pd_monitor = instance_del_data(inst, "pd,open,monitor");
if (pd_monitor) {
* Because they understand that the destroy request is successfully processed.
*/
ret = LB_STATUS_ERROR_CANCEL;
+ ret = instance_client_pd_created(inst, ret);
+ if (ret < 0)
+ ErrPrint("PD client create event: %d\n", ret);
+
+ ret = instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS);
+ if (ret < 0)
+ ErrPrint("PD client destroy event: %d\n", ret);
+
+ ret = instance_signal_emit(inst, "pd,hide", instance_id(inst), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
+ if (ret < 0)
+ ErrPrint("PD close signal emit failed: %d\n", ret);
+
+ ret = instance_slave_close_pd(inst, client);
+ if (ret < 0)
+ ErrPrint("PD close request failed: %d\n", ret);
- (void)instance_client_pd_created(inst, ret);
ecore_timer_del(pd_monitor);
(void)instance_unref(inst);
goto out;
}
+ pd_monitor = instance_del_data(inst, "pd,resize,monitor");
+ if (pd_monitor) {
+ ErrPrint("PD Resize request is found. clear it [%s]\n", pkgname);
+ ecore_timer_del(pd_monitor);
+
+ inst = instance_unref(inst);
+ if (!inst)
+ goto out;
+
+ resize_aborted = 1;
+ }
+
ret = instance_signal_emit(inst, "pd,hide", instance_id(inst), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
if (ret < 0)
ErrPrint("PD close signal emit failed: %d\n", ret);
if (ret < 0) {
ErrPrint("PD close request failed: %d\n", ret);
} else {
- pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_close_monitor_cb, instance_ref(inst));
- if (!pd_monitor) {
- (void)instance_unref(inst);
- ErrPrint("Failed to add pd close monitor\n");
+ if (resize_aborted) {
+ pd_monitor = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, instance_ref(inst));
+ if (!pd_monitor) {
+ ErrPrint("Failed to create a timer: %s\n", pkgname);
+ (void)instance_unref(inst);
+ } else {
+ (void)instance_set_data(inst, "lazy,pd,close", pd_monitor);
+ }
} else {
- (void)instance_set_data(inst, "pd,close,monitor", pd_monitor);
+ pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_close_monitor_cb, instance_ref(inst));
+ if (!pd_monitor) {
+ (void)instance_unref(inst);
+ ErrPrint("Failed to add pd close monitor\n");
+ } else {
+ (void)instance_set_data(inst, "pd,close,monitor", pd_monitor);
+ }
}
}
/*!
* instance_client_pd_destroyed(inst);
*/
} else if (package_pd_type(pkg) == PD_TYPE_SCRIPT) {
+ lazy_pd_created_cb(inst);
+
ret = script_handler_unload(instance_pd_script(inst), 1);
if (ret < 0)
ErrPrint("Unable to unload the script: %s, %d\n", pkgname, ret);
* Send the destroyed PD event to the client
*/
if (ret == LB_STATUS_SUCCESS) {
- Ecore_Timer *timer;
-
- inst = instance_ref(inst);
-
/*!
* \note
* 13-05-28
* But I just add it to the tagged-data of the instance.
* Just reserve for future-use.
*/
- timer = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, inst);
- if (!timer) {
+ pd_monitor = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, instance_ref(inst));
+ if (!pd_monitor) {
ErrPrint("Failed to create a timer: %s\n", pkgname);
(void)instance_unref(inst);
- /*!
- * How can we handle this?
- */
- ret = LB_STATUS_ERROR_FAULT;
} else {
- (void)instance_set_data(inst, "lazy,pd,close", timer);
+ (void)instance_set_data(inst, "lazy,pd,close", pd_monitor);
}
}
} else {
DbgPrint("New slave[%s](%d) is arrived\n", slavename, pid);
- slave = slave_find_by_pid(pid);
+ slave = slave_find_by_name(slavename);
+
+ if (!slave) /* Try again to find a slave using pid */
+ slave = slave_find_by_pid(pid);
+
if (!slave) {
if (DEBUG_MODE) {
char pkgname[pathconf("/", _PC_PATH_MAX)];
slave_set_pid(slave, pid);
DbgPrint("Provider is forcely activated, pkgname(%s), abi(%s), slavename(%s)\n", pkgname, abi, slavename);
} else {
- ErrPrint("Slave[%d] is not exists\n", pid);
+ ErrPrint("Slave[%d, %s] is not exists\n", pid, slavename);
goto out;
}
+ } else {
+ if (slave_pid(slave) != pid) {
+ if (slave_pid(slave) > 0) {
+ CRITICAL_LOG("Slave(%s) is already assigned to %d\n", slave_name(slave), slave_pid(slave));
+ if (pid > 0) {
+ ret = aul_terminate_pid(pid);
+ CRITICAL_LOG("Terminate %d (ret: %d)\n", pid, ret);
+ }
+ goto out;
+ }
+ CRITICAL_LOG("PID of slave(%s) is updated (%d -> %d)\n", slave_name(slave), slave_pid(slave), pid);
+ slave_set_pid(slave, pid);
+ }
}
/*!
} else if (instance_state(inst) == INST_DESTROYED) {
ErrPrint("Instance(%s) is already destroyed\n", id);
} else {
+ //clear_pd_monitor(inst);
ret = instance_destroy(inst);
}
}
ret = validate_request(pkgname, id, &inst, NULL);
- if (ret == LB_STATUS_SUCCESS)
+ if (ret == LB_STATUS_SUCCESS) {
+ //clear_pd_monitor(inst);
ret = instance_destroyed(inst);
+ }
out:
return NULL;
}
if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) {
- DbgPrint("No space\n");
+ ErrPrint("Not enough space\n");
ret = LB_STATUS_ERROR_NO_SPACE;
id = "";
goto out;
} else if (target == TYPE_PD && package_pd_type(pkg) == PD_TYPE_BUFFER) {
struct buffer_info *info;
Ecore_Timer *pd_monitor;
+ int is_resize;
+ is_resize = 0;
pd_monitor = instance_del_data(inst, "pd,open,monitor");
- if (!pd_monitor)
- goto out;
+ if (!pd_monitor) {
+ pd_monitor = instance_del_data(inst, "pd,resize,monitor");
+ is_resize = !!pd_monitor;
+ if (!is_resize)
+ goto out;
+ }
ecore_timer_del(pd_monitor);
inst = instance_unref(inst);
/*!
* Send the PD created event to the client
*/
- instance_client_pd_created(inst, ret);
+ if (!is_resize)
+ instance_client_pd_created(inst, ret);
}
out:
* by pd.need_to_send_close_event flag.
* which will be checked by instance_client_pd_destroyed function.
*/
+
+ /*!
+ * \note
+ * provider can try to resize the buffer size.
+ * in that case, it will release the buffer first.
+ * Then even though the client doesn't request to close the PD,
+ * the provider can release it.
+ * If we send the close event to the client,
+ * The client will not able to allocate PD again.
+ * In this case, add the pd,monitor again. from here.
+ * to wait the re-allocate buffer.
+ * If the client doesn't request buffer reallocation,
+ * Treat it as a fault. and close the PD.
+ */
+ info = instance_pd_buffer(inst);
+ ret = buffer_handler_unload(info);
+
+ if (ret == LB_STATUS_SUCCESS) {
+ pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_resize_monitor_cb, instance_ref(inst));
+ if (!pd_monitor) {
+ (void)instance_unref(inst);
+ ErrPrint("Failed to create a timer for PD Open monitor\n");
+ } else {
+ (void)instance_set_data(inst, "pd,resize,monitor", pd_monitor);
+ }
+ }
} else {
ecore_timer_del(pd_monitor);
inst = instance_unref(inst);
ret = LB_STATUS_ERROR_FAULT;
goto out;
}
- }
- info = instance_pd_buffer(inst);
- ret = buffer_handler_unload(info);
+ info = instance_pd_buffer(inst);
+ ret = buffer_handler_unload(info);
+
+ /*!
+ * \note
+ * Send the PD destroyed event to the client
+ */
+ instance_client_pd_destroyed(inst, ret);
+ }
- /*!
- * \note
- * Send the PD destroyed event to the client
- */
- instance_client_pd_destroyed(inst, ret);
}
out:
if (!inst) {
fprintf(fp, "%d\n", ENOENT);
} else {
- instance_destroy(inst);
+ //clear_pd_monitor(inst);
+ (void)instance_destroy(inst);
fprintf(fp, "%d\n", 0);
}
}