Made handle table a separate object.
[wine] / server / request.c
1 /*
2  * Server-side request handling
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <stdarg.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 #include <sys/uio.h>
15 #include <unistd.h>
16
17 #include "winerror.h"
18 #include "winnt.h"
19 #include "winbase.h"
20 #include "wincon.h"
21 #define WANT_REQUEST_HANDLERS
22 #include "server.h"
23 #include "thread.h"
24  
25 struct thread *current = NULL;  /* thread handling the current request */
26
27 /* complain about a protocol error and terminate the client connection */
28 void fatal_protocol_error( const char *err, ... )
29 {
30     va_list args;
31
32     va_start( args, err );
33     fprintf( stderr, "Protocol error:%p: ", current );
34     vfprintf( stderr, err, args );
35     va_end( args );
36     remove_client( current->client, -2 );
37 }
38
39 /* call a request handler */
40 void call_req_handler( struct thread *thread, enum request req,
41                        void *data, int len, int fd )
42 {
43     const struct handler *handler = &req_handlers[req];
44     char *ptr;
45
46     current = thread;
47     if ((req < 0) || (req >= REQ_NB_REQUESTS))
48     {
49         fatal_protocol_error( "unknown request %d\n", req );
50         return;
51     }
52
53     if (len < handler->min_size)
54     {
55         fatal_protocol_error( "req %d bad length %d < %d\n", req, len, handler->min_size );
56         return;
57     }
58
59     /* now call the handler */
60     if (current)
61     {
62         CLEAR_ERROR();
63         if (debug_level) trace_request( req, data, len, fd );
64     }
65     len -= handler->min_size;
66     ptr = (char *)data + handler->min_size;
67     handler->handler( data, ptr, len, fd );
68     current = NULL;
69 }
70
71 /* handle a client timeout */
72 void call_timeout_handler( void *thread )
73 {
74     current = (struct thread *)thread;
75     if (debug_level) trace_timeout();
76     CLEAR_ERROR();
77     thread_timeout();
78     current = NULL;
79 }
80
81 /* a thread has been killed */
82 void call_kill_handler( struct thread *thread, int exit_code )
83 {
84     /* must be reentrant WRT call_req_handler */
85     struct thread *old_current = current;
86     current = thread;
87     if (current)
88     {
89         if (debug_level) trace_kill( exit_code );
90         thread_killed( current, exit_code );
91     }
92     current = (old_current != thread) ? old_current : NULL;
93 }
94
95 /* set the debug level */
96 DECL_HANDLER(set_debug)
97 {
98     debug_level = req->level;
99     /* Make sure last_req is initialized */
100     current->last_req = REQ_SET_DEBUG;
101     CLEAR_ERROR();
102     send_reply( current, -1, 0 );
103 }
104
105 /* debugger support operations */
106 DECL_HANDLER(debugger)
107 {
108     switch ( req->op )
109     {
110     case DEBUGGER_FREEZE_ALL:
111         suspend_all_threads();
112         break;
113
114     case DEBUGGER_UNFREEZE_ALL:
115         resume_all_threads();
116         break;
117     }
118
119     send_reply( current, -1, 0 );
120 }