Moved a couple of locale functions from ole2nls.c into locale.c.
[wine] / server / async.c
1 /*
2  * Server-side support for async i/o operations
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  * Copyright (C) 2000 Mike McCormack
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <assert.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <stdio.h>
29
30 #include "handle.h"
31 #include "file.h"
32 #include "thread.h"
33 #include "request.h"
34
35 #include "async.h"
36
37 void destroy_async( struct async *async )
38 {
39     struct async_queue *aq = async->q;
40
41     /*fprintf(stderr,"destroyed async %p\n",async->overlapped); */
42
43     if(async->timeout)
44         remove_timeout_user(async->timeout);
45     async->timeout = NULL;
46
47     if(async->prev)
48         async->prev->next = async->next;
49     else
50         aq->head = async->next;
51
52     if(async->next)
53         async->next->prev = async->prev;
54     else
55         aq->tail = async->prev;
56
57     async->q = NULL;
58     async->next = NULL;
59     async->prev = NULL;
60     release_object( async->thread );
61     free(async);
62 }
63
64 void async_notify(struct async *async, int status)
65 {
66     /* fprintf(stderr,"notifying %p!\n",async->overlapped); */
67     async->status = status;
68     thread_queue_apc(async->thread, NULL, NULL, APC_ASYNC_IO, 1, 2, async->overlapped, status);
69 }
70
71 void destroy_async_queue( struct async_queue *q )
72 {
73     while(q->head)
74     {
75         async_notify(q->head, STATUS_CANCELLED);
76         destroy_async(q->head);
77     }
78 }
79
80 struct async *find_async(struct async_queue *q, struct thread *thread, void *overlapped)
81 {
82     struct async *async;
83
84     /* fprintf(stderr,"find_async: %p\n",overlapped); */
85
86     if(!q)
87         return NULL;
88
89     for(async = q->head; async; async = async->next)
90         if((async->overlapped==overlapped) && (async->thread == thread))
91              return async;
92
93     return NULL;
94 }
95
96 void async_insert(struct async_queue *q, struct async *async)
97 {
98     async->q = q;
99     async->prev = q->tail;
100     async->next = NULL;
101
102     if(q->tail)
103         q->tail->next = async;
104     else
105         q->head = async;
106
107     q->tail = async;
108 }
109
110 static void async_callback(void *private)
111 {
112     struct async *async = (struct async *)private;
113
114     /* fprintf(stderr,"%p timeout out\n",async->overlapped); */
115     async->timeout = NULL;
116     async_notify(async, STATUS_TIMEOUT);
117     destroy_async(async);
118 }
119
120 struct async *create_async(struct object *obj, struct thread *thread,
121                            void *overlapped)
122 {
123     struct async *async = (struct async *) malloc(sizeof(struct async));
124     if(!async)
125     {
126         set_error(STATUS_NO_MEMORY);
127         return NULL;
128     }
129
130     async->obj = obj;
131     async->thread = (struct thread *)grab_object(thread);
132     async->overlapped = overlapped;
133     async->next = NULL;
134     async->prev = NULL;
135     async->q = NULL;
136     async->status = STATUS_PENDING;
137     async->timeout = NULL;
138
139     return async;
140 }
141
142 void async_add_timeout(struct async *async, int timeout)
143 {
144     if(timeout)
145     {
146         gettimeofday( &async->when, 0 );
147         add_timeout( &async->when, timeout );
148         async->timeout = add_timeout_user( &async->when, async_callback, async );
149     }
150 }