Make sure a thread has a queue as soon as it creates a window.
diff --git a/server/queue.c b/server/queue.c
index c2fb9a9..83f908e 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -282,7 +282,7 @@
void set_queue_hooks( struct thread *thread, struct hook_table *hooks )
{
struct msg_queue *queue = thread->queue;
- if (!queue) queue = create_msg_queue( thread, NULL );
+ if (!queue && !(queue = create_msg_queue( thread, NULL ))) return;
if (queue->hooks) release_object( queue->hooks );
queue->hooks = hooks;
}
@@ -828,6 +828,13 @@
return ret;
}
+/* make sure the specified thread has a queue */
+int init_thread_queue( struct thread *thread )
+{
+ if (thread->queue) return 1;
+ return (create_msg_queue( thread, NULL ) != NULL);
+}
+
/* attach two thread input data structures */
int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
{
diff --git a/server/user.h b/server/user.h
index 874385d..36fd880 100644
--- a/server/user.h
+++ b/server/user.h
@@ -61,6 +61,7 @@
extern void set_queue_hooks( struct thread *thread, struct hook_table *hooks );
extern void inc_queue_paint_count( struct thread *thread, int incr );
extern void queue_cleanup_window( struct thread *thread, user_handle_t win );
+extern int init_thread_queue( struct thread *thread );
extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to );
extern void post_message( user_handle_t win, unsigned int message,
unsigned int wparam, unsigned int lparam );
diff --git a/server/window.c b/server/window.c
index ca3a98d..749d83e 100644
--- a/server/window.c
+++ b/server/window.c
@@ -338,13 +338,8 @@
release_class( class );
return NULL;
}
+ if (!(win->handle = alloc_user_handle( win, USER_WINDOW ))) goto failed;
- if (!(win->handle = alloc_user_handle( win, USER_WINDOW )))
- {
- release_class( class );
- free( win );
- return NULL;
- }
win->parent = parent;
win->owner = owner ? owner->handle : 0;
win->thread = current;
@@ -368,13 +363,26 @@
list_init( &win->children );
list_init( &win->unlinked );
+ /* if parent belongs to a different thread, attach the two threads */
+ if (parent && parent->thread && parent->thread != current)
+ {
+ if (!attach_thread_input( current, parent->thread )) goto failed;
+ }
+ else /* otherwise just make sure that the thread has a message queue */
+ {
+ if (!current->queue && !init_thread_queue( current )) goto failed;
+ }
+
/* put it on parent unlinked list */
if (parent) list_add_head( &parent->unlinked, &win->entry );
- /* if parent belongs to a different thread, attach the two threads */
- if (parent && parent->thread && parent->thread != current)
- attach_thread_input( current, parent->thread );
return win;
+
+failed:
+ if (win->handle) free_user_handle( win->handle );
+ release_class( class );
+ free( win );
+ return NULL;
}
/* destroy all windows belonging to a given thread */