1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Wine server threads
*
* Copyright (C) 1998 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_SERVER_THREAD_H
#define __WINE_SERVER_THREAD_H
#include "object.h"
/* thread structure */
struct process;
struct thread_wait;
struct thread_apc;
struct debug_ctx;
struct debug_event;
struct msg_queue;
enum run_state
{
RUNNING, /* running normally */
TERMINATED /* terminated */
};
/* descriptor for fds currently in flight from client to server */
struct inflight_fd
{
int client; /* fd on the client side (or -1 if entry is free) */
int server; /* fd on the server side */
};
#define MAX_INFLIGHT_FDS 16 /* max number of fds in flight per thread */
struct thread
{
struct object obj; /* object header */
struct list entry; /* entry in system-wide thread list */
struct list proc_entry; /* entry in per-process thread list */
struct process *process;
thread_id_t id; /* thread id */
struct list mutex_list; /* list of currently owned mutexes */
struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */
struct debug_event *debug_event; /* debug event being sent to debugger */
int debug_break; /* debug breakpoint pending? */
struct msg_queue *queue; /* message queue */
struct thread_wait *wait; /* current wait condition if sleeping */
struct list system_apc; /* queue of system async procedure calls */
struct list user_apc; /* queue of user async procedure calls */
struct inflight_fd inflight[MAX_INFLIGHT_FDS]; /* fds currently in flight */
unsigned int error; /* current error code */
union generic_request req; /* current request */
void *req_data; /* variable-size data for request */
unsigned int req_toread; /* amount of data still to read in request */
void *reply_data; /* variable-size data for reply */
unsigned int reply_size; /* size of reply data */
unsigned int reply_towrite; /* amount of data still to write in reply */
struct fd *request_fd; /* fd for receiving client requests */
struct fd *reply_fd; /* fd to send a reply to a client */
struct fd *wait_fd; /* fd to use to wake a sleeping client */
enum run_state state; /* running state */
int exit_code; /* thread exit code */
int unix_pid; /* Unix pid of client */
int unix_tid; /* Unix tid of client */
CONTEXT *context; /* current context if in an exception handler */
CONTEXT *suspend_context; /* current context if suspended */
void *teb; /* TEB address (in client address space) */
int priority; /* priority level */
unsigned int affinity; /* affinity mask */
int suspend; /* suspend count */
obj_handle_t desktop; /* desktop handle */
int desktop_users; /* number of objects using the thread desktop */
timeout_t creation_time; /* Thread creation time */
timeout_t exit_time; /* Thread exit time */
struct token *token; /* security token associated with this thread */
};
struct thread_snapshot
{
struct thread *thread; /* thread ptr */
int count; /* thread refcount */
int priority; /* priority class */
};
extern struct thread *current;
/* thread functions */
extern struct thread *create_thread( int fd, struct process *process );
extern struct thread *get_thread_from_id( thread_id_t id );
extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int access );
extern struct thread *get_thread_from_tid( int tid );
extern struct thread *get_thread_from_pid( int pid );
extern void stop_thread( struct thread *thread );
extern int wake_thread( struct thread *thread );
extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern void kill_thread( struct thread *thread, int violent_death );
extern void break_thread( struct thread *thread );
extern void wake_up( struct object *obj, int max );
extern int thread_queue_apc( struct thread *thread, struct object *owner, const apc_call_t *call_data );
extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum apc_type type );
extern int thread_add_inflight_fd( struct thread *thread, int client, int server );
extern int thread_get_inflight_fd( struct thread *thread, int client );
extern struct thread_snapshot *thread_snap( int *count );
extern struct token *thread_get_impersonation_token( struct thread *thread );
/* CPU context functions */
extern void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags );
extern void *get_context_ip( const CONTEXT *context );
extern unsigned int get_context_cpu_flag(void);
extern unsigned int get_context_system_regs( unsigned int flags );
/* ptrace functions */
extern void sigchld_callback(void);
extern void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags );
extern void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags );
extern int send_thread_signal( struct thread *thread, int sig );
extern void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
unsigned int *limit, unsigned char *flags );
extern unsigned int global_error; /* global error code for when no thread is current */
static inline unsigned int get_error(void) { return current ? current->error : global_error; }
static inline void set_error( unsigned int err ) { global_error = err; if (current) current->error = err; }
static inline void clear_error(void) { set_error(0); }
static inline void set_win32_error( unsigned int err ) { set_error( 0xc0010000 | err ); }
static inline thread_id_t get_thread_id( struct thread *thread ) { return thread->id; }
#endif /* __WINE_SERVER_THREAD_H */