properly shutdown of clients
This commit is contained in:
@@ -24,6 +24,7 @@ typedef struct private_dumm_t private_dumm_t;
|
|||||||
struct private_dumm_t {
|
struct private_dumm_t {
|
||||||
dumm_t public;
|
dumm_t public;
|
||||||
linked_list_t *guests;
|
linked_list_t *guests;
|
||||||
|
bool destroying;
|
||||||
};
|
};
|
||||||
|
|
||||||
static guest_t* create_guest(private_dumm_t *this, char *name, char *master, int mem)
|
static guest_t* create_guest(private_dumm_t *this, char *name, char *master, int mem)
|
||||||
@@ -48,6 +49,11 @@ static iterator_t* create_guest_iterator(private_dumm_t *this)
|
|||||||
*/
|
*/
|
||||||
static void sigchild_handler(private_dumm_t *this, siginfo_t *info)
|
static void sigchild_handler(private_dumm_t *this, siginfo_t *info)
|
||||||
{
|
{
|
||||||
|
if (this->destroying)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (info->si_code)
|
switch (info->si_code)
|
||||||
{
|
{
|
||||||
case CLD_EXITED:
|
case CLD_EXITED:
|
||||||
@@ -77,6 +83,17 @@ static void sigchild_handler(private_dumm_t *this, siginfo_t *info)
|
|||||||
|
|
||||||
static void destroy(private_dumm_t *this)
|
static void destroy(private_dumm_t *this)
|
||||||
{
|
{
|
||||||
|
iterator_t *iterator;
|
||||||
|
guest_t *guest;
|
||||||
|
|
||||||
|
iterator = this->guests->create_iterator(this->guests, TRUE);
|
||||||
|
while (iterator->iterate(iterator, (void**)&guest))
|
||||||
|
{
|
||||||
|
guest->stop(guest);
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
this->destroying = TRUE;
|
||||||
this->guests->destroy_offset(this->guests, offsetof(guest_t, destroy));
|
this->guests->destroy_offset(this->guests, offsetof(guest_t, destroy));
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -110,6 +127,7 @@ dumm_t *dumm_create()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->destroying = FALSE;
|
||||||
this->guests = linked_list_create();
|
this->guests = linked_list_create();
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -227,10 +227,10 @@ static void stop(private_guest_t *this)
|
|||||||
{
|
{
|
||||||
if (this->state != GUEST_STOPPED)
|
if (this->state != GUEST_STOPPED)
|
||||||
{
|
{
|
||||||
|
this->state = GUEST_STOPPING;
|
||||||
this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy));
|
this->ifaces->destroy_offset(this->ifaces, offsetof(iface_t, destroy));
|
||||||
this->ifaces = linked_list_create();
|
this->ifaces = linked_list_create();
|
||||||
kill(this->pid, SIGINT);
|
kill(this->pid, SIGINT);
|
||||||
this->state = GUEST_STOPPING;
|
|
||||||
while (this->state == GUEST_STOPPING)
|
while (this->state == GUEST_STOPPING)
|
||||||
{
|
{
|
||||||
sched_yield();
|
sched_yield();
|
||||||
@@ -243,6 +243,8 @@ static void stop(private_guest_t *this)
|
|||||||
*/
|
*/
|
||||||
static void sigchild(private_guest_t *this)
|
static void sigchild(private_guest_t *this)
|
||||||
{
|
{
|
||||||
|
DESTROY_IF(this->mconsole);
|
||||||
|
this->mconsole = NULL;
|
||||||
this->state = GUEST_STOPPED;
|
this->state = GUEST_STOPPED;
|
||||||
this->pid = 0;
|
this->pid = 0;
|
||||||
}
|
}
|
||||||
@@ -341,7 +343,6 @@ static void destroy(private_guest_t *this)
|
|||||||
{
|
{
|
||||||
stop(this);
|
stop(this);
|
||||||
umount_unionfs(this->name);
|
umount_unionfs(this->name);
|
||||||
DESTROY_IF(this->mconsole);
|
|
||||||
free(this->name);
|
free(this->name);
|
||||||
free(this->master);
|
free(this->master);
|
||||||
free(this);
|
free(this);
|
||||||
|
|||||||
+1
-4
@@ -395,10 +395,7 @@ void signal_action(int sig, siginfo_t *info, void *ucontext)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dumm->destroy(dumm);
|
printf("\nuse 'quit'\ndumm# ");
|
||||||
clear_history();
|
|
||||||
printf("\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user