extern void *instance_get_data(struct inst_info *inst, const char *tag);
extern void instance_reload_period(struct inst_info *inst, double period);
-extern struct packet *instance_duplicate_packet_create(struct inst_info *inst, struct pkg_info *info, int width, int height);
-extern struct packet *instance_watch_create(const char *pkgname, int width, int height);
+/**
+ * For the hello_sync or prepare_hello_sync command
+ */
+extern struct packet *instance_duplicate_packet_create(const struct packet *packet, struct inst_info *inst, struct pkg_info *info, int width, int height);
+extern struct packet *instance_watch_create(const struct packet *packet, const char *pkgname, int width, int height);
/* End of a file */
extern int slave_pause(struct slave_node *slave);
extern const char *slave_pkgname(const struct slave_node *slave);
-extern enum slave_state slave_state(const struct slave_node *slave);
extern const char *slave_state_string(const struct slave_node *slave);
+extern enum slave_state slave_state(const struct slave_node *slave);
+extern void slave_set_state(struct slave_node *slave, enum slave_state state);
+
extern const void *slave_list(void);
extern int const slave_fault_count(const struct slave_node *slave);
return inst;
}
-HAPI struct packet *instance_duplicate_packet_create(struct inst_info *inst, struct pkg_info *info, int width, int height)
+HAPI struct packet *instance_duplicate_packet_create(const struct packet *packet, struct inst_info *inst, struct pkg_info *info, int width, int height)
{
struct packet *result;
- unsigned int cmd = CMD_NEW;
/**
* Do not touch the "timestamp".
// inst->info = info;
inst->unicast_delete_event = 1;
- result = packet_create((const char *)&cmd, "sssiidssisiis",
+ result = packet_create_reply(packet, "sssiidssisiis",
package_name(inst->info),
inst->id,
inst->content,
return result;
}
+HAPI struct packet *instance_watch_create(const struct packet *packet, const char *pkgname, int width, int height)
+{
+ struct inst_info *inst;
+ struct packet *result;
+
+ inst = calloc(1, sizeof(*inst));
+ if (!inst) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ /**
+ * @note
+ * This timestamp will not be used by viewer.
+ * So we can set it manually from here.
+ */
+ inst->timestamp = util_timestamp();
+ inst->widget.width = width;
+ inst->widget.height = height;
+
+ if (fork_package(inst, pkgname) < 0) {
+ DbgFree(inst);
+ return NULL;
+ }
+
+ if (WIDGET_CONF_EXTRA_BUFFER_COUNT) {
+ inst->widget.extra_buffer = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*inst->widget.extra_buffer));
+ if (!inst->widget.extra_buffer) {
+ ErrPrint("Failed to allocate buffer for widget extra buffer\n");
+ }
+
+ inst->gbar.extra_buffer = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*inst->gbar.extra_buffer));
+ if (!inst->gbar.extra_buffer) {
+ ErrPrint("Failed to allocate buffer for gbar extra buffer\n");
+ }
+ }
+
+ /**
+ * We don't need to set the state of this instance from here.
+ * But, in case of fail to add a new instance to package information(inst->info) data,
+ * the "instance_destroy" will be invoked.
+ * it will try to get the state of an instance.
+ */
+ inst->state = INST_INIT;
+ inst->requested_state = INST_INIT;
+ instance_ref(inst);
+
+ /**
+ * @note
+ * We already create a slave object from caller.
+ * This will finds it and map it to package information object
+ */
+ if (package_add_instance(inst->info, inst) < 0) {
+ ErrPrint("Failed to package_add_instance\n");
+ unfork_package(inst);
+ DbgFree(inst->widget.extra_buffer);
+ DbgFree(inst->gbar.extra_buffer);
+ DbgFree(inst);
+ return NULL;
+ }
+
+ /**
+ * Before activate an instance, update its id first for client
+ instance_send_update_id(inst);
+ */
+ DbgPrint("[TODO] send_update_id\n");
+
+ result = packet_create_reply(packet, "sssiidssisiis",
+ package_name(inst->info),
+ inst->id,
+ inst->content,
+ package_timeout(inst->info),
+ !!package_widget_path(inst->info),
+ inst->widget.period,
+ inst->cluster,
+ inst->category,
+ !!inst->client,
+ package_abi(inst->info),
+ inst->widget.width,
+ inst->widget.height,
+ client_direct_addr(inst->client));
+
+ if (!result) {
+ ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
+ package_del_instance(inst->info, inst); /* This will reset the inst->info->slave */
+ unfork_package(inst);
+ DbgFree(inst->widget.extra_buffer);
+ DbgFree(inst->gbar.extra_buffer);
+ DbgFree(inst);
+ return NULL;
+ }
+
+ slave_load_instance(package_slave(inst->info));
+
+ inst->requested_state = INST_ACTIVATED;
+ inst->state = INST_ACTIVATED;
+
+ inst->visible = WIDGET_HIDE_WITH_PAUSE;
+
+ instance_create_widget_buffer(inst, WIDGET_CONF_DEFAULT_PIXELS);
+ instance_broadcast_created_event(inst);
+ instance_thaw_updator(inst);
+
+ return result;
+}
+
HAPI struct inst_info *instance_ref(struct inst_info *inst)
{
if (!inst) {
return inst->gbar.owner;
}
-HAPI struct packet *instance_watch_create(const char *pkgname, int width, int height)
-{
- struct inst_info *inst;
- struct packet *result;
- unsigned int cmd = CMD_NEW;
-
- inst = calloc(1, sizeof(*inst));
- if (!inst) {
- ErrPrint("Heap: %s\n", strerror(errno));
- return NULL;
- }
-
- /**
- * @note
- * This timestamp will not be used by viewer.
- * So we can set it manually from here.
- */
- inst->timestamp = util_timestamp();
- inst->widget.width = width;
- inst->widget.height = height;
-
- if (fork_package(inst, pkgname) < 0) {
- DbgFree(inst);
- return NULL;
- }
-
- if (WIDGET_CONF_EXTRA_BUFFER_COUNT) {
- inst->widget.extra_buffer = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*inst->widget.extra_buffer));
- if (!inst->widget.extra_buffer) {
- ErrPrint("Failed to allocate buffer for widget extra buffer\n");
- }
-
- inst->gbar.extra_buffer = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*inst->gbar.extra_buffer));
- if (!inst->gbar.extra_buffer) {
- ErrPrint("Failed to allocate buffer for gbar extra buffer\n");
- }
- }
-
- /**
- * We don't need to set the state of this instance from here.
- * But, in case of fail to add a new instance to package information(inst->info) data,
- * the "instance_destroy" will be invoked.
- * it will try to get the state of an instance.
- */
- inst->state = INST_INIT;
- inst->requested_state = INST_INIT;
- instance_ref(inst);
-
- /**
- * @note
- * We already create a slave object from caller.
- * This will finds it and map it to package information object
- */
- if (package_add_instance(inst->info, inst) < 0) {
- ErrPrint("Failed to package_add_instance\n");
- unfork_package(inst);
- DbgFree(inst->widget.extra_buffer);
- DbgFree(inst->gbar.extra_buffer);
- DbgFree(inst);
- return NULL;
- }
-
- /**
- * Before activate an instance, update its id first for client
- instance_send_update_id(inst);
- */
- DbgPrint("[TODO] send_update_id\n");
-
- result = packet_create((const char *)&cmd, "sssiidssisiis",
- package_name(inst->info),
- inst->id,
- inst->content,
- package_timeout(inst->info),
- !!package_widget_path(inst->info),
- inst->widget.period,
- inst->cluster,
- inst->category,
- !!inst->client,
- package_abi(inst->info),
- inst->widget.width,
- inst->widget.height,
- client_direct_addr(inst->client));
-
- if (!result) {
- ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
- package_del_instance(inst->info, inst); /* This will reset the inst->info->slave */
- unfork_package(inst);
- DbgFree(inst->widget.extra_buffer);
- DbgFree(inst->gbar.extra_buffer);
- DbgFree(inst);
- return NULL;
- }
-
- slave_load_instance(package_slave(inst->info));
-
- inst->requested_state = INST_ACTIVATED;
- inst->state = INST_ACTIVATED;
-
- inst->visible = WIDGET_HIDE_WITH_PAUSE;
-
- instance_create_widget_buffer(inst, WIDGET_CONF_DEFAULT_PIXELS);
- instance_broadcast_created_event(inst);
- instance_thaw_updator(inst);
-
- return result;
-}
-
/* End of a file */
goto out;
}
} else {
- char *widget_id;
- struct pkg_info *info;
- unsigned int widget_size;
- int network;
- int width;
- int height;
- struct inst_info *inst;
-
- widget_id = is_valid_slave(pid, abi, pkgname);
- if (!widget_id) {
- goto out;
- }
-
- info = package_find(widget_id);
-
- if (!info) {
- DbgPrint("There is no loaded package information\n");
- DbgFree(widget_id);
- goto out;
- } else {
- const char *category;
- const char *db_acceleration;
- int db_secured;
- const char *tmp;
-
- category = package_category(info);
- tmp = package_abi(info);
- db_secured = package_secured(info);
- db_acceleration = package_hw_acceleration(info);
-
- if (db_secured != secured) {
- DbgPrint("%s secured (%d)\n", pkgname, db_secured);
- DbgFree(widget_id);
- goto out;
- }
-
- if (strcmp(tmp, abi)) {
- DbgPrint("%s abi (%s)\n", pkgname, tmp);
- DbgFree(widget_id);
- goto out;
- }
-
- if (strcmp(acceleration, db_acceleration)) {
- DbgPrint("%s accel (%s)\n", pkgname, db_acceleration);
- DbgFree(widget_id);
- goto out;
- }
-
- if (util_string_is_in_list(category, WIDGET_CONF_CATEGORY_LIST) == 0) {
- DbgPrint("%s category (%s)\n", pkgname, category);
- DbgFree(widget_id);
- goto out;
- }
-
- network = package_network(info);
- }
-
- slave = slave_create(slavename, secured, abi, pkgname, network, acceleration, 0);
- if (!slave) {
- ErrPrint("Failed to create a new slave for %s\n", slavename);
- DbgFree(widget_id);
- goto out;
- }
-
- slave_set_pid(slave, pid);
- slave_set_valid(slave);
- slave_activated(slave);
- DbgPrint("Slave is activated by request: %d (%s)/(%s)\n", pid, pkgname, slavename);
-
- widget_size = package_size_list(info);
-
- if (widget_size & WIDGET_SIZE_TYPE_2x2) {
- widget_service_get_size(WIDGET_SIZE_TYPE_2x2, &width, &height);
- } else if (widget_size & WIDGET_SIZE_TYPE_4x4) {
- widget_service_get_size(WIDGET_SIZE_TYPE_4x4, &width, &height);
- } else {
- widget_service_get_size(WIDGET_SIZE_TYPE_1x1, &width, &height);
- DbgPrint("widget[%s] doesn't support size [2x2], [4x4]\n", pkgname);
- }
-
- /**
- * @note
- * Create an instance by provider's request.
- * And then assign its client when a viewer tries to create this instance.
- */
- inst = instance_create(NULL, util_timestamp(), widget_id, "", "", "", WIDGET_CONF_DEFAULT_PERIOD, width, height);
- if (!inst) {
- ErrPrint("Failed to create a new instance\n");
- }
-
- DbgFree(widget_id);
+ ErrPrint("Request comes from unknown: %d\n", pid);
+ ret = aul_terminate_pid_async(pid);
+ DbgPrint("Terminate %d (%d)\n", pid, ret);
+ goto out;
}
} else {
if (slave_pid(slave) != pid) {
goto out;
}
+ /**
+ * @note
+ * To send the pause/resume event to the provider, reverse set its state from here
+ */
+ slave_set_state(slave, xmonitor_is_paused() ? SLAVE_RESUMED : SLAVE_PAUSED);
+
DbgPrint("Update handle for %s (%d)\n", pkgname, handle);
slave_rpc_update_handle(slave, handle, 1);
} else {
slave_set_pid(slave, pid);
slave_set_valid(slave);
- /**
- * @note
- * In this case, there could not be exists any pended packets.
- * But we tried to clear them for a case!
- */
if (handle >= 0) {
+ /**
+ * @note
+ * To send the pause/resume event to the provider, reverse set its state from here
+ */
+ slave_set_state(slave, xmonitor_is_paused() ? SLAVE_RESUMED : SLAVE_PAUSED);
+
+ /**
+ * @note
+ * In this case, there could not be exists any pended packets.
+ * But we tried to clear them for a case!
+ */
slave_rpc_update_handle(slave, handle, 1);
} else {
DbgPrint("Slave RPC should be updated soon (waiting prepare sync)\n");
DbgPrint("widget(%s] does not support size [2x2], [4x4]\n",pkgname);
}
- result = instance_watch_create(widget_id, width, height);
+ result = instance_watch_create(packet, widget_id, width, height);
if (!result) {
ErrPrint("Failed to create a new instance\n");
if (slave_unref(slave)) {
}
if (handle >= 0) {
+ /**
+ * @note
+ * To send the pause/resume event to the provider, reverse set its state from here
+ */
+ slave_set_state(slave, xmonitor_is_paused() ? SLAVE_RESUMED : SLAVE_PAUSED);
+
slave_rpc_update_handle(slave, handle, 1);
+
+ /**
+ * @note
+ * This PAUSE/RESUME state will be sent to the provider after the instance is created.
+ * Because, this command is sync. so there is no way to get the state packet first then create packet.
+ */
} else {
DbgPrint("Slave RPC should be updated soon (waiting prepare sync)\n");
}
DbgPrint("widget(%s] does not support size [2x2], [4x4]\n",pkgname);
}
- result = instance_duplicate_packet_create(inst, info, width, height);
+ result = instance_duplicate_packet_create(packet, inst, info, width, height);
DbgFree(widget_id);
}
HAPI int slave_activated(struct slave_node *slave)
{
- slave->state = SLAVE_RESUMED;
+ /**
+ * @note
+ * Send the client's state to the provider.
+ * After the slave is activated.
+ */
+ if (xmonitor_is_paused()) {
+ slave_pause(slave);
+ } else {
+ slave_resume(slave);
+ }
/**
* Condition for activating TTL Timer
return slave ? slave->state : SLAVE_ERROR;
}
+HAPI void slave_set_state(struct slave_node *slave, enum slave_state state)
+{
+ slave->state = state;
+}
+
HAPI const char *slave_state_string(const struct slave_node *slave)
{
switch (slave->state) {