Moved idle event handling to the server.
This commit is contained in:
parent
9baa51e1c0
commit
c5e433a3a6
@ -91,8 +91,6 @@ typedef struct _PDB
|
|||||||
HANDLE *dos_handles; /* Handles mapping DOS -> Win32 */
|
HANDLE *dos_handles; /* Handles mapping DOS -> Win32 */
|
||||||
WORD winver; /* Windows version figured out by VERSION_GetVersion */
|
WORD winver; /* Windows version figured out by VERSION_GetVersion */
|
||||||
struct _SERVICETABLE *service_table; /* Service table for service thread */
|
struct _SERVICETABLE *service_table; /* Service table for service thread */
|
||||||
HANDLE idle_event; /* event to signal, when the process is idle */
|
|
||||||
HANDLE16 main_queue; /* main message queue of the process */
|
|
||||||
} PDB;
|
} PDB;
|
||||||
|
|
||||||
/* Process flags */
|
/* Process flags */
|
||||||
|
@ -90,7 +90,7 @@ typedef struct tagMESSAGEQUEUE
|
|||||||
HQUEUE16 next; /* Next queue */
|
HQUEUE16 next; /* Next queue */
|
||||||
HQUEUE16 self; /* Handle to self (was: reserved) */
|
HQUEUE16 self; /* Handle to self (was: reserved) */
|
||||||
TEB* teb; /* Thread owning queue */
|
TEB* teb; /* Thread owning queue */
|
||||||
HANDLE hEvent; /* Event handle */
|
HANDLE server_queue; /* Handle to server-side queue */
|
||||||
CRITICAL_SECTION cSection; /* Queue access critical section */
|
CRITICAL_SECTION cSection; /* Queue access critical section */
|
||||||
|
|
||||||
DWORD magic; /* magic number should be QUEUE_MAGIC */
|
DWORD magic; /* magic number should be QUEUE_MAGIC */
|
||||||
|
@ -170,6 +170,7 @@ struct init_process_done_request
|
|||||||
{
|
{
|
||||||
IN void* module; /* main module base address */
|
IN void* module; /* main module base address */
|
||||||
IN void* entry; /* process entry point */
|
IN void* entry; /* process entry point */
|
||||||
|
IN int gui; /* is it a GUI process? */
|
||||||
OUT int debugged; /* being debugged? */
|
OUT int debugged; /* being debugged? */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1147,6 +1148,29 @@ struct get_atom_name_request
|
|||||||
OUT WCHAR name[1]; /* atom name */
|
OUT WCHAR name[1]; /* atom name */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the message queue of the current thread */
|
||||||
|
struct get_msg_queue_request
|
||||||
|
{
|
||||||
|
OUT int handle; /* handle to the queue */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Wake up a message queue */
|
||||||
|
struct wake_queue_request
|
||||||
|
{
|
||||||
|
IN int handle; /* handle to the queue */
|
||||||
|
IN unsigned int bits; /* wake bits */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Wait for a process to start waiting on input */
|
||||||
|
struct wait_input_idle_request
|
||||||
|
{
|
||||||
|
IN int handle; /* process handle */
|
||||||
|
IN int timeout; /* timeout */
|
||||||
|
OUT int event; /* handle to idle event */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Everything below this line is generated automatically by tools/make_requests */
|
/* Everything below this line is generated automatically by tools/make_requests */
|
||||||
/* ### make_requests begin ### */
|
/* ### make_requests begin ### */
|
||||||
|
|
||||||
@ -1255,10 +1279,13 @@ enum request
|
|||||||
REQ_DELETE_ATOM,
|
REQ_DELETE_ATOM,
|
||||||
REQ_FIND_ATOM,
|
REQ_FIND_ATOM,
|
||||||
REQ_GET_ATOM_NAME,
|
REQ_GET_ATOM_NAME,
|
||||||
|
REQ_GET_MSG_QUEUE,
|
||||||
|
REQ_WAKE_QUEUE,
|
||||||
|
REQ_WAIT_INPUT_IDLE,
|
||||||
REQ_NB_REQUESTS
|
REQ_NB_REQUESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 12
|
#define SERVER_PROTOCOL_VERSION 13
|
||||||
|
|
||||||
/* ### make_requests end ### */
|
/* ### make_requests end ### */
|
||||||
/* Everything above this line is generated automatically by tools/make_requests */
|
/* Everything above this line is generated automatically by tools/make_requests */
|
||||||
|
@ -187,7 +187,6 @@ BOOL PROCESS_Init(void)
|
|||||||
pdb->group = pdb;
|
pdb->group = pdb;
|
||||||
pdb->priority = 8; /* Normal */
|
pdb->priority = 8; /* Normal */
|
||||||
pdb->winver = 0xffff; /* to be determined */
|
pdb->winver = 0xffff; /* to be determined */
|
||||||
pdb->main_queue = INVALID_HANDLE_VALUE16;
|
|
||||||
initial_envdb.startup_info = &initial_startup;
|
initial_envdb.startup_info = &initial_startup;
|
||||||
|
|
||||||
/* Setup the server connection */
|
/* Setup the server connection */
|
||||||
@ -218,14 +217,6 @@ BOOL PROCESS_Init(void)
|
|||||||
if (!HEAP_CreateSystemHeap()) return FALSE;
|
if (!HEAP_CreateSystemHeap()) return FALSE;
|
||||||
pdb->heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
|
pdb->heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
|
||||||
|
|
||||||
/* Create the idle event for the initial process
|
|
||||||
FIXME 1: Shouldn't we call UserSignalProc for the initial process too?
|
|
||||||
FIXME 2: It seems to me that the initial pdb becomes never freed, so I don't now
|
|
||||||
where to release the idle event for the initial process.
|
|
||||||
*/
|
|
||||||
pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
|
|
||||||
pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
|
|
||||||
|
|
||||||
/* Copy the parent environment */
|
/* Copy the parent environment */
|
||||||
if (!ENV_BuildEnvironment()) return FALSE;
|
if (!ENV_BuildEnvironment()) return FALSE;
|
||||||
|
|
||||||
@ -332,7 +323,7 @@ static void start_process(void)
|
|||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
struct init_process_done_request *req = get_req_buffer();
|
struct init_process_done_request *req = get_req_buffer();
|
||||||
int debugged;
|
int debugged, console_app;
|
||||||
HMODULE16 hModule16;
|
HMODULE16 hModule16;
|
||||||
UINT cmdShow = SW_SHOWNORMAL;
|
UINT cmdShow = SW_SHOWNORMAL;
|
||||||
LPTHREAD_START_ROUTINE entry;
|
LPTHREAD_START_ROUTINE entry;
|
||||||
@ -347,6 +338,7 @@ static void start_process(void)
|
|||||||
|
|
||||||
/* Retrieve entry point address */
|
/* Retrieve entry point address */
|
||||||
entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint );
|
entry = (LPTHREAD_START_ROUTINE)RVA_PTR( module, OptionalHeader.AddressOfEntryPoint );
|
||||||
|
console_app = (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
|
||||||
|
|
||||||
/* Create 16-bit dummy module */
|
/* Create 16-bit dummy module */
|
||||||
if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32)
|
if ((hModule16 = MODULE_CreateDummyModule( pdb->exe_modref->filename, module )) < 32)
|
||||||
@ -358,12 +350,12 @@ static void start_process(void)
|
|||||||
NtCurrentTeb(), NULL, 0 ))
|
NtCurrentTeb(), NULL, 0 ))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (PE_HEADER(module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
if (console_app) pdb->flags |= PDB32_CONSOLE_PROC;
|
||||||
pdb->flags |= PDB32_CONSOLE_PROC;
|
|
||||||
|
|
||||||
/* Signal the parent process to continue */
|
/* Signal the parent process to continue */
|
||||||
req->module = (void *)module;
|
req->module = (void *)module;
|
||||||
req->entry = entry;
|
req->entry = entry;
|
||||||
|
req->gui = !console_app;
|
||||||
server_call( REQ_INIT_PROCESS_DONE );
|
server_call( REQ_INIT_PROCESS_DONE );
|
||||||
debugged = req->debugged;
|
debugged = req->debugged;
|
||||||
|
|
||||||
@ -376,8 +368,7 @@ static void start_process(void)
|
|||||||
LeaveCriticalSection( &pdb->crit_section );
|
LeaveCriticalSection( &pdb->crit_section );
|
||||||
|
|
||||||
/* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
|
/* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
|
||||||
if (pdb->flags & PDB32_CONSOLE_PROC)
|
if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
|
||||||
PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
|
|
||||||
|
|
||||||
TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
|
TRACE_(relay)( "Starting Win32 process (entryproc=%p)\n", entry );
|
||||||
if (debugged) DbgBreakPoint();
|
if (debugged) DbgBreakPoint();
|
||||||
|
@ -22,6 +22,7 @@ C_SRCS = \
|
|||||||
pipe.c \
|
pipe.c \
|
||||||
process.c \
|
process.c \
|
||||||
ptrace.c \
|
ptrace.c \
|
||||||
|
queue.c \
|
||||||
registry.c \
|
registry.c \
|
||||||
request.c \
|
request.c \
|
||||||
select.c \
|
select.c \
|
||||||
|
@ -72,6 +72,14 @@ struct object
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wait_queue_entry
|
||||||
|
{
|
||||||
|
struct wait_queue_entry *next;
|
||||||
|
struct wait_queue_entry *prev;
|
||||||
|
struct object *obj;
|
||||||
|
struct thread *thread;
|
||||||
|
};
|
||||||
|
|
||||||
extern void *mem_alloc( size_t size ); /* malloc wrapper */
|
extern void *mem_alloc( size_t size ); /* malloc wrapper */
|
||||||
extern void *memdup( const void *data, size_t len );
|
extern void *memdup( const void *data, size_t len );
|
||||||
extern void *alloc_object( const struct object_ops *ops, int fd );
|
extern void *alloc_object( const struct object_ops *ops, int fd );
|
||||||
|
@ -137,6 +137,8 @@ static int set_process_console( struct process *process, struct process *parent,
|
|||||||
req->hstderr = alloc_handle( process, process->console_out,
|
req->hstderr = alloc_handle( process, process->console_out,
|
||||||
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
|
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
|
||||||
}
|
}
|
||||||
|
/* some handles above may have been invalid; this is not an error */
|
||||||
|
if (get_error() == STATUS_INVALID_HANDLE) clear_error();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +167,8 @@ struct thread *create_process( int fd )
|
|||||||
process->console_in = NULL;
|
process->console_in = NULL;
|
||||||
process->console_out = NULL;
|
process->console_out = NULL;
|
||||||
process->init_event = NULL;
|
process->init_event = NULL;
|
||||||
|
process->idle_event = NULL;
|
||||||
|
process->queue = NULL;
|
||||||
process->ldt_copy = NULL;
|
process->ldt_copy = NULL;
|
||||||
process->ldt_flags = NULL;
|
process->ldt_flags = NULL;
|
||||||
process->exe.next = NULL;
|
process->exe.next = NULL;
|
||||||
@ -282,6 +286,8 @@ static void process_destroy( struct object *obj )
|
|||||||
if (process->prev) process->prev->next = process->next;
|
if (process->prev) process->prev->next = process->next;
|
||||||
else first_process = process->next;
|
else first_process = process->next;
|
||||||
if (process->init_event) release_object( process->init_event );
|
if (process->init_event) release_object( process->init_event );
|
||||||
|
if (process->idle_event) release_object( process->idle_event );
|
||||||
|
if (process->queue) release_object( process->queue );
|
||||||
if (process->exe.file) release_object( process->exe.file );
|
if (process->exe.file) release_object( process->exe.file );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,6 +819,7 @@ DECL_HANDLER(init_process_done)
|
|||||||
set_event( process->init_event );
|
set_event( process->init_event );
|
||||||
release_object( process->init_event );
|
release_object( process->init_event );
|
||||||
process->init_event = NULL;
|
process->init_event = NULL;
|
||||||
|
if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
|
||||||
if (current->suspend + current->process->suspend > 0) stop_thread( current );
|
if (current->suspend + current->process->suspend > 0) stop_thread( current );
|
||||||
req->debugged = (current->process->debugger != 0);
|
req->debugged = (current->process->debugger != 0);
|
||||||
}
|
}
|
||||||
@ -919,3 +926,19 @@ DECL_HANDLER(unload_dll)
|
|||||||
{
|
{
|
||||||
process_unload_dll( current->process, req->base );
|
process_unload_dll( current->process, req->base );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wait for a process to start waiting on input */
|
||||||
|
/* FIXME: only returns event for now, wait is done in the client */
|
||||||
|
DECL_HANDLER(wait_input_idle)
|
||||||
|
{
|
||||||
|
struct process *process;
|
||||||
|
|
||||||
|
req->event = -1;
|
||||||
|
if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
|
||||||
|
{
|
||||||
|
if (process->idle_event && process != current->process && process->queue != current->queue)
|
||||||
|
req->event = alloc_handle( current->process, process->idle_event,
|
||||||
|
EVENT_ALL_ACCESS, 0 );
|
||||||
|
release_object( process );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
|
struct msg_queue;
|
||||||
|
|
||||||
/* process structures */
|
/* process structures */
|
||||||
|
|
||||||
struct process_dll
|
struct process_dll
|
||||||
@ -45,6 +47,8 @@ struct process
|
|||||||
struct object *console_in; /* console input */
|
struct object *console_in; /* console input */
|
||||||
struct object *console_out; /* console output */
|
struct object *console_out; /* console output */
|
||||||
struct event *init_event; /* event for init done */
|
struct event *init_event; /* event for init done */
|
||||||
|
struct event *idle_event; /* event for input idle */
|
||||||
|
struct msg_queue *queue; /* main message queue */
|
||||||
struct process_dll exe; /* main exe file */
|
struct process_dll exe; /* main exe file */
|
||||||
void *ldt_copy; /* pointer to LDT copy in client addr space */
|
void *ldt_copy; /* pointer to LDT copy in client addr space */
|
||||||
void *ldt_flags; /* pointer to LDT flags in client addr space */
|
void *ldt_flags; /* pointer to LDT flags in client addr space */
|
||||||
|
130
server/queue.c
Normal file
130
server/queue.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Server-side message queues
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000 Alexandre Julliard
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "handle.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "request.h"
|
||||||
|
|
||||||
|
struct msg_queue
|
||||||
|
{
|
||||||
|
struct object obj; /* object header */
|
||||||
|
struct thread *thread; /* thread owning this queue */
|
||||||
|
int signaled; /* queue has been signaled */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void msg_queue_dump( struct object *obj, int verbose );
|
||||||
|
static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry );
|
||||||
|
static void msg_queue_remove_queue( struct object *obj, struct wait_queue_entry *entry );
|
||||||
|
static int msg_queue_signaled( struct object *obj, struct thread *thread );
|
||||||
|
static int msg_queue_satisfied( struct object *obj, struct thread *thread );
|
||||||
|
|
||||||
|
static const struct object_ops msg_queue_ops =
|
||||||
|
{
|
||||||
|
sizeof(struct msg_queue), /* size */
|
||||||
|
msg_queue_dump, /* dump */
|
||||||
|
msg_queue_add_queue, /* add_queue */
|
||||||
|
msg_queue_remove_queue, /* remove_queue */
|
||||||
|
msg_queue_signaled, /* signaled */
|
||||||
|
msg_queue_satisfied, /* satisfied */
|
||||||
|
NULL, /* get_poll_events */
|
||||||
|
NULL, /* poll_event */
|
||||||
|
no_read_fd, /* get_read_fd */
|
||||||
|
no_write_fd, /* get_write_fd */
|
||||||
|
no_flush, /* flush */
|
||||||
|
no_get_file_info, /* get_file_info */
|
||||||
|
no_destroy /* destroy */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct msg_queue *create_msg_queue( struct thread *thread )
|
||||||
|
{
|
||||||
|
struct msg_queue *queue;
|
||||||
|
|
||||||
|
if ((queue = alloc_object( &msg_queue_ops, -1 )))
|
||||||
|
{
|
||||||
|
queue->signaled = 0;
|
||||||
|
queue->thread = thread;
|
||||||
|
thread->queue = queue;
|
||||||
|
if (!thread->process->queue)
|
||||||
|
thread->process->queue = (struct msg_queue *)grab_object( queue );
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = (struct msg_queue *)obj;
|
||||||
|
struct process *process = entry->thread->process;
|
||||||
|
|
||||||
|
/* if waiting on the main process queue, set the idle event */
|
||||||
|
if (entry->thread == queue->thread && process->queue == queue)
|
||||||
|
{
|
||||||
|
if (process->idle_event) set_event( process->idle_event );
|
||||||
|
}
|
||||||
|
add_queue( obj, entry );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry *entry )
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = (struct msg_queue *)obj;
|
||||||
|
struct process *process = entry->thread->process;
|
||||||
|
|
||||||
|
remove_queue( obj, entry );
|
||||||
|
|
||||||
|
/* if waiting on the main process queue, reset the idle event */
|
||||||
|
if (entry->thread == queue->thread && process->queue == queue)
|
||||||
|
{
|
||||||
|
if (process->idle_event) reset_event( process->idle_event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msg_queue_dump( struct object *obj, int verbose )
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = (struct msg_queue *)obj;
|
||||||
|
fprintf( stderr, "Msg queue signaled=%d owner=%p\n", queue->signaled, queue->thread );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msg_queue_signaled( struct object *obj, struct thread *thread )
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = (struct msg_queue *)obj;
|
||||||
|
return queue->signaled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msg_queue_satisfied( struct object *obj, struct thread *thread )
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = (struct msg_queue *)obj;
|
||||||
|
queue->signaled = 0;
|
||||||
|
return 0; /* Not abandoned */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the message queue of the current thread */
|
||||||
|
DECL_HANDLER(get_msg_queue)
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = current->queue;
|
||||||
|
|
||||||
|
req->handle = -1;
|
||||||
|
if (!queue) queue = create_msg_queue( current );
|
||||||
|
if (queue) req->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wake up a message queue */
|
||||||
|
DECL_HANDLER(wake_queue)
|
||||||
|
{
|
||||||
|
struct msg_queue *queue = (struct msg_queue *)get_handle_obj( current->process, req->handle,
|
||||||
|
0, &msg_queue_ops );
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
queue->signaled = 1;
|
||||||
|
wake_up( &queue->obj, 0 );
|
||||||
|
release_object( queue );
|
||||||
|
}
|
||||||
|
}
|
@ -173,6 +173,9 @@ DECL_HANDLER(add_atom);
|
|||||||
DECL_HANDLER(delete_atom);
|
DECL_HANDLER(delete_atom);
|
||||||
DECL_HANDLER(find_atom);
|
DECL_HANDLER(find_atom);
|
||||||
DECL_HANDLER(get_atom_name);
|
DECL_HANDLER(get_atom_name);
|
||||||
|
DECL_HANDLER(get_msg_queue);
|
||||||
|
DECL_HANDLER(wake_queue);
|
||||||
|
DECL_HANDLER(wait_input_idle);
|
||||||
|
|
||||||
#ifdef WANT_REQUEST_HANDLERS
|
#ifdef WANT_REQUEST_HANDLERS
|
||||||
|
|
||||||
@ -282,6 +285,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||||||
(req_handler)req_delete_atom,
|
(req_handler)req_delete_atom,
|
||||||
(req_handler)req_find_atom,
|
(req_handler)req_find_atom,
|
||||||
(req_handler)req_get_atom_name,
|
(req_handler)req_get_atom_name,
|
||||||
|
(req_handler)req_get_msg_queue,
|
||||||
|
(req_handler)req_wake_queue,
|
||||||
|
(req_handler)req_wait_input_idle,
|
||||||
};
|
};
|
||||||
#endif /* WANT_REQUEST_HANDLERS */
|
#endif /* WANT_REQUEST_HANDLERS */
|
||||||
|
|
||||||
|
@ -34,14 +34,6 @@
|
|||||||
|
|
||||||
/* thread queues */
|
/* thread queues */
|
||||||
|
|
||||||
struct wait_queue_entry
|
|
||||||
{
|
|
||||||
struct wait_queue_entry *next;
|
|
||||||
struct wait_queue_entry *prev;
|
|
||||||
struct object *obj;
|
|
||||||
struct thread *thread;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct thread_wait
|
struct thread_wait
|
||||||
{
|
{
|
||||||
int count; /* count of objects */
|
int count; /* count of objects */
|
||||||
@ -131,6 +123,7 @@ struct thread *create_thread( int fd, struct process *process )
|
|||||||
thread->mutex = NULL;
|
thread->mutex = NULL;
|
||||||
thread->debug_ctx = NULL;
|
thread->debug_ctx = NULL;
|
||||||
thread->debug_event = NULL;
|
thread->debug_event = NULL;
|
||||||
|
thread->queue = NULL;
|
||||||
thread->info = NULL;
|
thread->info = NULL;
|
||||||
thread->wait = NULL;
|
thread->wait = NULL;
|
||||||
thread->apc = NULL;
|
thread->apc = NULL;
|
||||||
@ -196,6 +189,7 @@ static void destroy_thread( struct object *obj )
|
|||||||
else first_thread = thread->next;
|
else first_thread = thread->next;
|
||||||
if (thread->apc) free( thread->apc );
|
if (thread->apc) free( thread->apc );
|
||||||
if (thread->info) release_object( thread->info );
|
if (thread->info) release_object( thread->info );
|
||||||
|
if (thread->queue) release_object( thread->queue );
|
||||||
if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
|
if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH );
|
||||||
if (thread->pass_fd != -1) close( thread->pass_fd );
|
if (thread->pass_fd != -1) close( thread->pass_fd );
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ struct mutex;
|
|||||||
struct debug_ctx;
|
struct debug_ctx;
|
||||||
struct debug_event;
|
struct debug_event;
|
||||||
struct startup_info;
|
struct startup_info;
|
||||||
|
struct msg_queue;
|
||||||
|
|
||||||
enum run_state
|
enum run_state
|
||||||
{
|
{
|
||||||
@ -41,6 +42,7 @@ struct thread
|
|||||||
struct mutex *mutex; /* list of currently owned mutexes */
|
struct mutex *mutex; /* list of currently owned mutexes */
|
||||||
struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */
|
struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */
|
||||||
struct debug_event *debug_event; /* debug event being sent to debugger */
|
struct debug_event *debug_event; /* debug event being sent to debugger */
|
||||||
|
struct msg_queue *queue; /* message queue */
|
||||||
struct startup_info*info; /* startup info for child process */
|
struct startup_info*info; /* startup info for child process */
|
||||||
struct thread_wait *wait; /* current wait condition if sleeping */
|
struct thread_wait *wait; /* current wait condition if sleeping */
|
||||||
struct thread_apc *apc; /* list of async procedure calls */
|
struct thread_apc *apc; /* list of async procedure calls */
|
||||||
|
@ -284,7 +284,8 @@ static void dump_init_process_reply( const struct init_process_request *req )
|
|||||||
static void dump_init_process_done_request( const struct init_process_done_request *req )
|
static void dump_init_process_done_request( const struct init_process_done_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " module=%p,", req->module );
|
fprintf( stderr, " module=%p,", req->module );
|
||||||
fprintf( stderr, " entry=%p", req->entry );
|
fprintf( stderr, " entry=%p,", req->entry );
|
||||||
|
fprintf( stderr, " gui=%d", req->gui );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_init_process_done_reply( const struct init_process_done_request *req )
|
static void dump_init_process_done_reply( const struct init_process_done_request *req )
|
||||||
@ -1333,6 +1334,32 @@ static void dump_get_atom_name_reply( const struct get_atom_name_request *req )
|
|||||||
dump_unicode_string( req, req->name );
|
dump_unicode_string( req, req->name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_get_msg_queue_request( const struct get_msg_queue_request *req )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_get_msg_queue_reply( const struct get_msg_queue_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%d", req->handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_wake_queue_request( const struct wake_queue_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%d,", req->handle );
|
||||||
|
fprintf( stderr, " bits=%08x", req->bits );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_wait_input_idle_request( const struct wait_input_idle_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%d,", req->handle );
|
||||||
|
fprintf( stderr, " timeout=%d", req->timeout );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_wait_input_idle_reply( const struct wait_input_idle_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " event=%d", req->event );
|
||||||
|
}
|
||||||
|
|
||||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_new_process_request,
|
(dump_func)dump_new_process_request,
|
||||||
(dump_func)dump_wait_process_request,
|
(dump_func)dump_wait_process_request,
|
||||||
@ -1437,6 +1464,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)dump_delete_atom_request,
|
(dump_func)dump_delete_atom_request,
|
||||||
(dump_func)dump_find_atom_request,
|
(dump_func)dump_find_atom_request,
|
||||||
(dump_func)dump_get_atom_name_request,
|
(dump_func)dump_get_atom_name_request,
|
||||||
|
(dump_func)dump_get_msg_queue_request,
|
||||||
|
(dump_func)dump_wake_queue_request,
|
||||||
|
(dump_func)dump_wait_input_idle_request,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
@ -1543,6 +1573,9 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)dump_find_atom_reply,
|
(dump_func)dump_find_atom_reply,
|
||||||
(dump_func)dump_get_atom_name_reply,
|
(dump_func)dump_get_atom_name_reply,
|
||||||
|
(dump_func)dump_get_msg_queue_reply,
|
||||||
|
(dump_func)0,
|
||||||
|
(dump_func)dump_wait_input_idle_reply,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
@ -1649,6 +1682,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||||||
"delete_atom",
|
"delete_atom",
|
||||||
"find_atom",
|
"find_atom",
|
||||||
"get_atom_name",
|
"get_atom_name",
|
||||||
|
"get_msg_queue",
|
||||||
|
"wake_queue",
|
||||||
|
"wait_input_idle",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ### make_requests end ### */
|
/* ### make_requests end ### */
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "winproc.h"
|
#include "winproc.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "process.h"
|
|
||||||
#include "selectors.h"
|
#include "selectors.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
@ -31,9 +30,9 @@
|
|||||||
#include "struct32.h"
|
#include "struct32.h"
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
|
||||||
DEFAULT_DEBUG_CHANNEL(msg)
|
DEFAULT_DEBUG_CHANNEL(msg);
|
||||||
DECLARE_DEBUG_CHANNEL(key)
|
DECLARE_DEBUG_CHANNEL(key);
|
||||||
DECLARE_DEBUG_CHANNEL(sendmsg)
|
DECLARE_DEBUG_CHANNEL(sendmsg);
|
||||||
|
|
||||||
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
|
#define WM_NCMOUSEFIRST WM_NCMOUSEMOVE
|
||||||
#define WM_NCMOUSELAST WM_NCMBUTTONDBLCLK
|
#define WM_NCMOUSELAST WM_NCMBUTTONDBLCLK
|
||||||
@ -1952,7 +1951,6 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles,
|
|||||||
DWORD i;
|
DWORD i;
|
||||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
|
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
PDB * pdb = PROCESS_Current();
|
|
||||||
|
|
||||||
HQUEUE16 hQueue = GetFastQueue16();
|
HQUEUE16 hQueue = GetFastQueue16();
|
||||||
MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
|
MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
|
||||||
@ -1988,7 +1986,6 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles,
|
|||||||
/*
|
/*
|
||||||
* Check the handles in the list.
|
* Check the handles in the list.
|
||||||
*/
|
*/
|
||||||
SetEvent ( pdb->idle_event );
|
|
||||||
ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 5L);
|
ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 5L);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2021,17 +2018,10 @@ DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles,
|
|||||||
/* Add the thread event to the handle list */
|
/* Add the thread event to the handle list */
|
||||||
for (i = 0; i < nCount; i++)
|
for (i = 0; i < nCount; i++)
|
||||||
handles[i] = pHandles[i];
|
handles[i] = pHandles[i];
|
||||||
handles[nCount] = msgQueue->hEvent;
|
handles[nCount] = msgQueue->server_queue;
|
||||||
|
|
||||||
if ( pdb->main_queue == INVALID_HANDLE_VALUE16 ) pdb->main_queue = hQueue;
|
|
||||||
if ( pdb->main_queue == hQueue ) SetEvent ( pdb->idle_event );
|
|
||||||
ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
|
ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
|
||||||
if ( pdb->main_queue == hQueue ) ResetEvent ( pdb->idle_event );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QUEUE_Unlock( msgQueue );
|
QUEUE_Unlock( msgQueue );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,12 @@
|
|||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "process.h"
|
|
||||||
#include "debugtools.h"
|
#include "debugtools.h"
|
||||||
|
#include "server.h"
|
||||||
#include "spy.h"
|
#include "spy.h"
|
||||||
|
|
||||||
DECLARE_DEBUG_CHANNEL(msg)
|
DECLARE_DEBUG_CHANNEL(msg);
|
||||||
DECLARE_DEBUG_CHANNEL(sendmsg)
|
DECLARE_DEBUG_CHANNEL(sendmsg);
|
||||||
|
|
||||||
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
|
#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */
|
||||||
|
|
||||||
@ -342,8 +342,8 @@ void QUEUE_Unlock( MESSAGEQUEUE *queue )
|
|||||||
if ( --queue->lockCount == 0 )
|
if ( --queue->lockCount == 0 )
|
||||||
{
|
{
|
||||||
DeleteCriticalSection ( &queue->cSection );
|
DeleteCriticalSection ( &queue->cSection );
|
||||||
if (queue->hEvent)
|
if (queue->server_queue)
|
||||||
CloseHandle( queue->hEvent );
|
CloseHandle( queue->server_queue );
|
||||||
GlobalFree16( queue->self );
|
GlobalFree16( queue->self );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,6 +443,7 @@ static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData )
|
|||||||
HQUEUE16 hQueue;
|
HQUEUE16 hQueue;
|
||||||
MESSAGEQUEUE * msgQueue;
|
MESSAGEQUEUE * msgQueue;
|
||||||
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||||
|
struct get_msg_queue_request *req = get_req_buffer();
|
||||||
|
|
||||||
TRACE_(msg)("(): Creating message queue...\n");
|
TRACE_(msg)("(): Creating message queue...\n");
|
||||||
|
|
||||||
@ -454,6 +455,15 @@ static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData )
|
|||||||
if ( !msgQueue )
|
if ( !msgQueue )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (server_call( REQ_GET_MSG_QUEUE ))
|
||||||
|
{
|
||||||
|
ERR_(msg)("Cannot get thread queue");
|
||||||
|
GlobalFree16( hQueue );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
msgQueue->server_queue = req->handle;
|
||||||
|
msgQueue->server_queue = ConvertToGlobalHandle( msgQueue->server_queue );
|
||||||
|
|
||||||
msgQueue->self = hQueue;
|
msgQueue->self = hQueue;
|
||||||
msgQueue->wakeBits = msgQueue->changeBits = 0;
|
msgQueue->wakeBits = msgQueue->changeBits = 0;
|
||||||
msgQueue->wWinVersion = pTask ? pTask->version : 0;
|
msgQueue->wWinVersion = pTask ? pTask->version : 0;
|
||||||
@ -461,22 +471,6 @@ static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData )
|
|||||||
InitializeCriticalSection( &msgQueue->cSection );
|
InitializeCriticalSection( &msgQueue->cSection );
|
||||||
MakeCriticalSectionGlobal( &msgQueue->cSection );
|
MakeCriticalSectionGlobal( &msgQueue->cSection );
|
||||||
|
|
||||||
/* Create an Event object for waiting on message, used by win32 thread
|
|
||||||
only */
|
|
||||||
if ( !THREAD_IsWin16( NtCurrentTeb() ) )
|
|
||||||
{
|
|
||||||
msgQueue->hEvent = CreateEventA( NULL, FALSE, FALSE, NULL);
|
|
||||||
|
|
||||||
if (msgQueue->hEvent == 0)
|
|
||||||
{
|
|
||||||
WARN_(msg)("CreateEventA is not able to create an event object");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
msgQueue->hEvent = ConvertToGlobalHandle( msgQueue->hEvent );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
msgQueue->hEvent = 0;
|
|
||||||
|
|
||||||
msgQueue->lockCount = 1;
|
msgQueue->lockCount = 1;
|
||||||
msgQueue->magic = QUEUE_MAGIC;
|
msgQueue->magic = QUEUE_MAGIC;
|
||||||
|
|
||||||
@ -645,7 +639,10 @@ void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetEvent( queue->hEvent );
|
struct wake_queue_request *req = get_req_buffer();
|
||||||
|
req->handle = queue->server_queue;
|
||||||
|
req->bits = bit;
|
||||||
|
server_call( REQ_WAKE_QUEUE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,7 +672,6 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
|||||||
MESSAGEQUEUE *queue;
|
MESSAGEQUEUE *queue;
|
||||||
DWORD curTime = 0;
|
DWORD curTime = 0;
|
||||||
HQUEUE16 hQueue;
|
HQUEUE16 hQueue;
|
||||||
PDB * pdb;
|
|
||||||
|
|
||||||
TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
|
TRACE_(msg)("q %04x waiting for %04x\n", GetFastQueue16(), bits);
|
||||||
|
|
||||||
@ -685,8 +681,6 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
|||||||
hQueue = GetFastQueue16();
|
hQueue = GetFastQueue16();
|
||||||
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return 0;
|
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue ))) return 0;
|
||||||
|
|
||||||
pdb = PROCESS_Current();
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (queue->changeBits & bits)
|
if (queue->changeBits & bits)
|
||||||
@ -724,22 +718,7 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
|||||||
ReleaseThunkLock( &dwlc );
|
ReleaseThunkLock( &dwlc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WaitForSingleObject( queue->server_queue, timeout );
|
||||||
if ( pdb->main_queue == INVALID_HANDLE_VALUE16 )
|
|
||||||
{
|
|
||||||
pdb->main_queue = hQueue;
|
|
||||||
}
|
|
||||||
if ( pdb->main_queue == hQueue )
|
|
||||||
{
|
|
||||||
SetEvent ( pdb->idle_event );
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitForSingleObject( queue->hEvent, timeout );
|
|
||||||
|
|
||||||
if ( pdb->main_queue == hQueue )
|
|
||||||
{
|
|
||||||
ResetEvent ( pdb->idle_event );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( bHasWin16Lock )
|
if ( bHasWin16Lock )
|
||||||
{
|
{
|
||||||
@ -748,8 +727,6 @@ int QUEUE_WaitBits( WORD bits, DWORD timeout )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetEvent ( pdb->idle_event );
|
|
||||||
|
|
||||||
if ( timeout == INFINITE )
|
if ( timeout == INFINITE )
|
||||||
WaitEvent16( 0 ); /* win 16 thread, use WaitEvent */
|
WaitEvent16( 0 ); /* win 16 thread, use WaitEvent */
|
||||||
else
|
else
|
||||||
@ -1522,34 +1499,21 @@ BOOL16 WINAPI GetInputState16(void)
|
|||||||
*/
|
*/
|
||||||
DWORD WINAPI WaitForInputIdle (HANDLE hProcess, DWORD dwTimeOut)
|
DWORD WINAPI WaitForInputIdle (HANDLE hProcess, DWORD dwTimeOut)
|
||||||
{
|
{
|
||||||
PDB * pdb;
|
DWORD cur_time, ret;
|
||||||
DWORD cur_time, ret, pid = MapProcessHandle ( hProcess );
|
HANDLE idle_event;
|
||||||
|
struct wait_input_idle_request *req = get_req_buffer();
|
||||||
|
|
||||||
/* Check whether the calling process is a command line application */
|
req->handle = hProcess;
|
||||||
if (!THREAD_IsWin16(NtCurrentTeb() ) &&
|
req->timeout = dwTimeOut;
|
||||||
(PROCESS_Current()->flags & PDB32_CONSOLE_PROC))
|
if (server_call( REQ_WAIT_INPUT_IDLE )) return 0xffffffff;
|
||||||
{
|
if ((idle_event = req->event) == -1) return 0; /* no event to wait on */
|
||||||
TRACE_(msg)("not a win32 GUI application!\n" );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(pdb = PROCESS_IdToPDB( pid ))) return 0;
|
|
||||||
|
|
||||||
/* check whether we are waiting for a win32 process or the win16 subsystem */
|
|
||||||
if ( pdb->flags & PDB32_WIN16_PROC ) {
|
|
||||||
if ( THREAD_IsWin16(NtCurrentTeb()) ) return 0;
|
|
||||||
}
|
|
||||||
else { /* target is win32 */
|
|
||||||
if ( pdb->flags & PDB32_CONSOLE_PROC ) return 0;
|
|
||||||
if ( GetFastQueue16() == pdb->main_queue ) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_time = GetTickCount();
|
cur_time = GetTickCount();
|
||||||
|
|
||||||
TRACE_(msg)("waiting for %x\n", pdb->idle_event );
|
TRACE_(msg)("waiting for %x\n", idle_event );
|
||||||
while ( dwTimeOut > GetTickCount() - cur_time || dwTimeOut == INFINITE ) {
|
while ( dwTimeOut > GetTickCount() - cur_time || dwTimeOut == INFINITE ) {
|
||||||
|
|
||||||
ret = MsgWaitForMultipleObjects ( 1, &pdb->idle_event, FALSE, dwTimeOut, QS_SENDMESSAGE );
|
ret = MsgWaitForMultipleObjects ( 1, &idle_event, FALSE, dwTimeOut, QS_SENDMESSAGE );
|
||||||
if ( ret == ( WAIT_OBJECT_0 + 1 )) {
|
if ( ret == ( WAIT_OBJECT_0 + 1 )) {
|
||||||
MESSAGEQUEUE * queue;
|
MESSAGEQUEUE * queue;
|
||||||
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0xFFFFFFFF;
|
if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0xFFFFFFFF;
|
||||||
|
@ -210,9 +210,7 @@ void WINAPI FinalUserInit16( void )
|
|||||||
WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
|
WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
|
||||||
DWORD dwFlags, HMODULE16 hModule )
|
DWORD dwFlags, HMODULE16 hModule )
|
||||||
{
|
{
|
||||||
static HANDLE win16_idle_event;
|
|
||||||
HINSTANCE16 hInst;
|
HINSTANCE16 hInst;
|
||||||
PDB * pdb;
|
|
||||||
|
|
||||||
/* FIXME: Proper reaction to most signals still missing. */
|
/* FIXME: Proper reaction to most signals still missing. */
|
||||||
|
|
||||||
@ -239,32 +237,12 @@ WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USIG_PROCESS_CREATE:
|
case USIG_PROCESS_CREATE:
|
||||||
pdb = PROCESS_Current();
|
|
||||||
|
|
||||||
/* Create the idle event for the process. We have just one idle_event for all
|
|
||||||
win16 processes, while each win32 process has its own */
|
|
||||||
|
|
||||||
if ( pdb->flags & PDB32_WIN16_PROC )
|
|
||||||
{
|
|
||||||
if (!win16_idle_event)
|
|
||||||
{
|
|
||||||
win16_idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
|
|
||||||
win16_idle_event = ConvertToGlobalHandle ( win16_idle_event );
|
|
||||||
}
|
|
||||||
pdb->idle_event = win16_idle_event;
|
|
||||||
}
|
|
||||||
else { /* win32 process */
|
|
||||||
pdb->idle_event = CreateEventA ( NULL, TRUE, FALSE, NULL );
|
|
||||||
pdb->idle_event = ConvertToGlobalHandle ( pdb->idle_event );
|
|
||||||
TRACE_(win)("created win32 idle event: %x\n", pdb->idle_event );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USIG_PROCESS_INIT:
|
case USIG_PROCESS_INIT:
|
||||||
case USIG_PROCESS_LOADED:
|
case USIG_PROCESS_LOADED:
|
||||||
break;
|
break;
|
||||||
case USIG_PROCESS_RUNNING:
|
case USIG_PROCESS_RUNNING:
|
||||||
SetEvent ( PROCESS_Current()->idle_event );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USIG_PROCESS_EXIT:
|
case USIG_PROCESS_EXIT:
|
||||||
@ -273,12 +251,6 @@ WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
|
|||||||
case USIG_PROCESS_DESTROY:
|
case USIG_PROCESS_DESTROY:
|
||||||
hInst = ((TDB *)GlobalLock16( GetCurrentTask() ))->hInstance;
|
hInst = ((TDB *)GlobalLock16( GetCurrentTask() ))->hInstance;
|
||||||
USER_AppExit( hInst );
|
USER_AppExit( hInst );
|
||||||
|
|
||||||
pdb = PROCESS_Current();
|
|
||||||
if ( ! (pdb->flags & PDB32_WIN16_PROC) ) {
|
|
||||||
TRACE_(win)("destroying win32 idle event: %x\n", pdb->idle_event );
|
|
||||||
CloseHandle ( pdb->idle_event );
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user