~ubuntu-branches/debian/squeeze/nas/squeeze

« back to all changes in this revision

Viewing changes to server/dia/dispatch.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve McIntyre
  • Date: 2008-10-08 01:18:19 UTC
  • mfrom: (4.1.7 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081008011819-wmr4h2w0298k8t7z
Tags: 1.9.1-5
* Fix pending l10n issues. Debconf translations:
* Swedish. Closes: #491766 (thanks to brother@bsnet.se)
* Arabic. Closes: #500437 (thanks to Ossama Khayat)
* Basque. Closes: #500533 (thanks to Piarres Beobide)
* Brazilian Portuguese. Closes: #500973 (thanks to Felipe
  Augusto van de Wiel)
* Many thanks again to Christian Perrier for his i18n efforts,
  co-ordinating the above.

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
 
48
48
********************************************************/
49
49
 
50
 
#include        <audio/audio.h>
51
 
#include        <audio/Aproto.h>
 
50
#include <audio/audio.h>
 
51
#include <audio/Aproto.h>
 
52
#include "misc.h"
52
53
#include "dixstruct.h"
53
 
#include "osstruct.h"
 
54
#include "os.h"
54
55
#include "opaque.h"
55
 
#include "servermd.h"
56
56
 
57
 
extern void     ProcessAudioEvents(), SendAuErrorToClient(),
58
 
                SwapConnClientPrefix(), ResetCurrentRequest(), WriteToClient();
59
 
extern int      CompareTimeStamps(), WaitForSomething(), AuSendInitResponse();
60
 
extern Bool     ClientIsAsleep(), ClientSignal();
 
57
extern void ProcessAudioEvents(), SendAuErrorToClient(),
 
58
SwapConnClientPrefix(), ResetCurrentRequest(), WriteToClient();
 
59
extern int CompareTimeStamps(), WaitForSomething(), AuSendInitResponse();
61
60
 
62
61
#define mskcnt ((MAXCLIENTS + 31) / 32)
63
62
#define BITMASK(i) (1 << ((i) & 31))
70
69
extern void NotImplemented();
71
70
extern Bool InitClientResources();
72
71
 
73
 
extern int (* InitialVector[3]) ();
74
 
extern void Swap32Write(), WriteSConnectionInfo();
 
72
extern int (*InitialVector[3]) ();
75
73
extern void WriteSConnSetupPrefix();
76
74
extern char *ClientAuthorized();
77
75
extern Bool InsertFakeRequest();
78
 
static void KillAllClients();
79
 
extern void ProcessWorkQueue();
80
 
 
81
 
extern int (* AuProcVector[256]) ();
82
 
extern int (* AuSwappedProcVector[256]) ();
83
 
extern void (* AuEventSwapVector[256]) ();
84
 
extern void (* AuReplySwapVector[256]) ();
85
 
 
86
 
static int nextFreeClientID; /* always MIN free client ID */
87
 
 
88
 
static int      nClients;       /* number active clients */
 
76
static void KillAllClients(void);
 
77
 
 
78
extern int (*AuProcVector[256]) ();
 
79
extern int (*AuSwappedProcVector[256]) ();
 
80
extern void (*AuEventSwapVector[256]) ();
 
81
extern void (*AuReplySwapVector[256]) ();
 
82
 
 
83
static int nextFreeClientID;    /* always MIN free client ID */
 
84
 
 
85
static int nClients;            /* number active clients */
89
86
 
90
87
char dispatchException = 0;
91
88
char isItTimeToYield;
95
92
 * Rather than changing interfaces and breaking untold code we introduce
96
93
 * a new global that dispatch can use.
97
94
 */
98
 
AuID clientErrorValue;   /* XXX this is a kludge */
99
 
 
100
 
void
101
 
UpdateCurrentTime()
102
 
{
103
 
    TimeStamp systime;
104
 
 
105
 
    /* To avoid time running backwards, we must call GetTimeInMillis before
106
 
     * calling ProcessInputEvents.
107
 
     */
108
 
    systime.months = currentTime.months;
109
 
    systime.milliseconds = GetTimeInMillis();
110
 
    if (systime.milliseconds < currentTime.milliseconds)
111
 
        systime.months++;
112
 
    ProcessAudioEvents();
113
 
    if (CompareTimeStamps(systime, currentTime) == LATER)
114
 
        currentTime = systime;
115
 
}
 
95
AuID clientErrorValue;          /* XXX this is a kludge */
116
96
 
117
97
/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
118
98
void
119
 
UpdateCurrentTimeIf()
 
99
UpdateCurrentTimeIf(void)
120
100
{
121
101
    TimeStamp systime;
122
102
 
123
103
    systime.months = currentTime.months;
124
104
    systime.milliseconds = GetTimeInMillis();
125
105
    if (systime.milliseconds < currentTime.milliseconds)
126
 
        systime.months++;
 
106
        systime.months++;
127
107
 
128
108
    currentTime = systime;
129
109
}
133
113
void
134
114
Dispatch()
135
115
{
136
 
    register int        *clientReady;     /* array of request ready clients */
137
 
    register int        result;
138
 
    register ClientPtr  client;
139
 
    register int        nready;
 
116
    int *clientReady;  /* array of request ready clients */
 
117
    int result;
 
118
    ClientPtr client;
 
119
    int nready;
140
120
 
141
121
    nextFreeClientID = 1;
142
122
    nClients = 0;
143
123
 
144
124
    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
145
125
    if (!clientReady)
146
 
        return;
147
 
 
148
 
    while (!dispatchException)
149
 
    {
150
 
        FlushIfCriticalOutputPending();
151
 
 
152
 
        ProcessAudioEvents();
153
 
 
154
 
        nready = WaitForSomething(clientReady);
 
126
        return;
 
127
 
 
128
    while (!dispatchException) {
 
129
        FlushIfCriticalOutputPending();
 
130
 
 
131
        ProcessAudioEvents();
 
132
 
 
133
        nready = WaitForSomething(clientReady);
155
134
 
156
135
       /***************** 
157
 
        *  Handle events in round robin fashion, doing input between 
158
 
        *  each round 
159
 
        *****************/
160
 
 
161
 
        while (!dispatchException && (--nready >= 0))
162
 
        {
163
 
            client = clients[clientReady[nready]];
164
 
            if (! client)
165
 
            {
166
 
                /* KillClient can cause this to happen */
167
 
                continue;
168
 
            }
169
 
            isItTimeToYield = FALSE;
170
 
 
171
 
            while (!isItTimeToYield)
172
 
            {
173
 
                FlushIfCriticalOutputPending();
174
 
 
175
 
                ProcessAudioEvents();
176
 
           
177
 
                /* now, finally, deal with client requests */
178
 
 
179
 
                result = ReadRequestFromClient(client);
180
 
                if (result <= 0) 
181
 
                {
182
 
                    if (result < 0)
183
 
                        CloseDownClient(client);
184
 
                    break;
185
 
                }
186
 
 
187
 
                client->sequence++;
 
136
        *  Handle events in round robin fashion, doing input between 
 
137
        *  each round 
 
138
        *****************/
 
139
 
 
140
        while (!dispatchException && (--nready >= 0)) {
 
141
            client = clients[clientReady[nready]];
 
142
            if (!client) {
 
143
                /* KillClient can cause this to happen */
 
144
                continue;
 
145
            }
 
146
            isItTimeToYield = FALSE;
 
147
 
 
148
            while (!isItTimeToYield) {
 
149
                FlushIfCriticalOutputPending();
 
150
 
 
151
                ProcessAudioEvents();
 
152
 
 
153
                /* now, finally, deal with client requests */
 
154
 
 
155
                result = ReadRequestFromClient(client);
 
156
                if (result <= 0) {
 
157
                    if (result < 0)
 
158
                        CloseDownClient(client);
 
159
                    break;
 
160
                }
 
161
 
 
162
                client->sequence++;
188
163
#ifdef DEBUG
189
 
                if (client->requestLogIndex == MAX_REQUEST_LOG)
190
 
                    client->requestLogIndex = 0;
191
 
                client->requestLog[client->requestLogIndex] = MAJOROP;
192
 
                client->requestLogIndex++;
 
164
                if (client->requestLogIndex == MAX_REQUEST_LOG)
 
165
                    client->requestLogIndex = 0;
 
166
                client->requestLog[client->requestLogIndex] = MAJOROP;
 
167
                client->requestLogIndex++;
193
168
#endif
194
 
                if (result > (MAX_BIG_REQUEST_SIZE << 2))
195
 
                    result = AuBadLength;
196
 
                else
197
 
                    result = (* client->requestVector[MAJOROP])(client);
198
 
            
199
 
                if (result != AuSuccess) 
200
 
                {
201
 
                    if (client->noClientException != AuSuccess)
 
169
                if (result > (MAX_BIG_REQUEST_SIZE << 2))
 
170
                    result = AuBadLength;
 
171
                else
 
172
                    result = (*client->requestVector[MAJOROP]) (client);
 
173
 
 
174
                if (result != AuSuccess) {
 
175
                    if (client->noClientException != AuSuccess)
202
176
                        CloseDownClient(client);
203
177
                    else
204
 
                        SendAuErrorToClient(client, MAJOROP,
205
 
                                          0, client->errorValue, result);
206
 
                    break;
207
 
                }
208
 
            }
209
 
            FlushAllOutput();
210
 
        }
 
178
                        SendAuErrorToClient(client, MAJOROP,
 
179
                                            0, client->errorValue, result);
 
180
                    break;
 
181
                }
 
182
            }
 
183
            FlushAllOutput();
 
184
        }
211
185
    }
212
186
    KillAllClients();
213
187
    DEALLOCATE_LOCAL(clientReady);
216
190
 
217
191
#undef MAJOROP
218
192
 
219
 
/*ARGSUSED*/
220
 
int
221
 
ProcBadRequest(client)
222
 
    ClientPtr client;
 
193
 /*ARGSUSED*/ int
 
194
ProcBadRequest(ClientPtr client)
223
195
{
224
196
    return (AuBadRequest);
225
197
}
226
198
 
227
199
void
228
 
AuInitProcVectors()
 
200
AuInitProcVectors(void)
229
201
{
230
202
    int i;
231
203
 
232
 
    for (i = 0; i < 256; i++)
233
 
    {
234
 
        if(!AuProcVector[i])
235
 
        {
 
204
    for (i = 0; i < 256; i++) {
 
205
        if (!AuProcVector[i]) {
236
206
            AuProcVector[i] = AuSwappedProcVector[i] = ProcBadRequest;
237
 
            AuReplySwapVector[i] = NotImplemented;
238
 
        }
 
207
            AuReplySwapVector[i] = NotImplemented;
 
208
        }
239
209
    }
240
210
 
241
211
    for (i = AuLastEventType + 1; i < 256; i++)
242
 
        AuEventSwapVector[i] = NotImplemented;
 
212
        AuEventSwapVector[i] = NotImplemented;
243
213
}
244
214
 
245
215
extern int Ones();
254
224
Bool terminateAtReset = FALSE;
255
225
 
256
226
void
257
 
CloseDownClient(client)
258
 
    register ClientPtr client;
 
227
CloseDownClient(ClientPtr client)
259
228
{
260
 
    if (!client->clientGone)
261
 
    {
262
 
            client->clientGone = TRUE;  /* so events aren't sent to client */
263
 
            CloseDownConnection(client);
264
 
 
265
 
        if (client->closeDownMode == AuCloseDownDestroy)
266
 
        {
267
 
            FreeClientResources(client);
268
 
            if (ClientIsAsleep (client))
269
 
                ClientSignal (client);
270
 
            if (client->index < nextFreeClientID)
271
 
                nextFreeClientID = client->index;
272
 
            clients[client->index] = NullClient;
273
 
 
274
 
            /* Pebl: decrease first as the compiler might skip the second test
275
 
             * if first fails, then check if client was idle.  BUG: if a
276
 
             * persistent client is running flows all flows are killed if
277
 
             * there is no more clients, except if it was the only client.  */
278
 
            if ((--nClients == 0) &&
279
 
                (client->requestVector != InitialVector))
280
 
            {
281
 
                if (terminateAtReset)
282
 
                    dispatchException |= DE_TERMINATE;
283
 
                else
284
 
                    dispatchException |= DE_RESET;
285
 
            }
286
 
            xfree(client);
287
 
        }
288
 
        else
289
 
        {
290
 
            --nClients;
291
 
        }
292
 
    }
293
 
    else
294
 
    {
295
 
        /* really kill resources this time */
 
229
    if (!client->clientGone) {
 
230
        client->clientGone = TRUE;      /* so events aren't sent to client */
 
231
        CloseDownConnection(client);
 
232
 
 
233
        if (client->closeDownMode == AuCloseDownDestroy) {
 
234
            FreeClientResources(client);
 
235
            if (client->index < nextFreeClientID)
 
236
                nextFreeClientID = client->index;
 
237
            clients[client->index] = NullClient;
 
238
 
 
239
            /* Pebl: decrease first as the compiler might skip the second test
 
240
             * if first fails, then check if client was idle.  BUG: if a
 
241
             * persistent client is running flows all flows are killed if
 
242
             * there is no more clients, except if it was the only client.  */
 
243
            if ((--nClients == 0) &&
 
244
                (client->requestVector != InitialVector)) {
 
245
                if (terminateAtReset)
 
246
                    dispatchException |= DE_TERMINATE;
 
247
                else
 
248
                    dispatchException |= DE_RESET;
 
249
            }
 
250
            xfree(client);
 
251
        } else {
 
252
            --nClients;
 
253
        }
 
254
    } else {
 
255
        /* really kill resources this time */
296
256
        FreeClientResources(client);
297
 
        if (ClientIsAsleep (client))
298
 
            ClientSignal (client);
299
 
        if (client->index < nextFreeClientID)
300
 
            nextFreeClientID = client->index;
301
 
        clients[client->index] = NullClient;
 
257
        if (client->index < nextFreeClientID)
 
258
            nextFreeClientID = client->index;
 
259
        clients[client->index] = NullClient;
302
260
        xfree(client);
303
261
    }
304
262
 
305
 
    while (!clients[currentMaxClients-1])
306
 
      currentMaxClients--;
 
263
    while (!clients[currentMaxClients - 1])
 
264
        currentMaxClients--;
307
265
}
308
266
 
309
267
static void
310
 
KillAllClients()
 
268
KillAllClients(void)
311
269
{
312
270
    int i;
313
 
    for (i=1; i<currentMaxClients; i++)
 
271
    for (i = 1; i < currentMaxClients; i++)
314
272
        if (clients[i])
315
 
            CloseDownClient(clients[i]);     
 
273
            CloseDownClient(clients[i]);
316
274
}
317
275
 
318
276
/*********************
322
280
 *    and  destroy their resources.
323
281
 *********************/
324
282
void
325
 
CloseDownRetainedResources()
 
283
CloseDownRetainedResources(void)
326
284
{
327
 
    register int i;
328
 
    register ClientPtr client;
 
285
    int i;
 
286
    ClientPtr client;
329
287
 
330
 
    for (i=1; i<currentMaxClients; i++)
331
 
    {
 
288
    for (i = 1; i < currentMaxClients; i++) {
332
289
        client = clients[i];
333
290
        if (client && (client->closeDownMode == AuCloseDownRetainTemporary)
334
 
            && (client->clientGone))
335
 
            CloseDownClient(client);
 
291
            && (client->clientGone))
 
292
            CloseDownClient(client);
336
293
    }
337
294
}
338
295
 
339
 
void InitClient(client, i, ospriv)
340
 
    ClientPtr client;
341
 
    int i;
342
 
    pointer ospriv;
 
296
void
 
297
InitClient(ClientPtr client, int i, pointer ospriv)
343
298
{
344
299
    client->index = i;
345
 
    client->sequence = 0; 
346
 
    client->clientAsMask = ((AuMask)i) << CLIENTOFFSET;
 
300
    client->sequence = 0;
 
301
    client->clientAsMask = ((AuMask) i) << CLIENTOFFSET;
347
302
    client->clientGone = FALSE;
348
303
    client->noClientException = AuSuccess;
349
304
#ifdef DEBUG
355
310
    client->big_requests = FALSE;
356
311
    client->closeDownMode = AuCloseDownDestroy;
357
312
    /* pebl: init unused field? */
358
 
    bzero(client->screenPrivate,MAXSCREENS * sizeof(pointer));
 
313
    bzero(client->screenPrivate, MAXSCREENS * sizeof(pointer));
359
314
}
360
315
 
361
316
/************************
366
321
 *************************/
367
322
 
368
323
ClientPtr
369
 
NextAvailableClient(ospriv)
370
 
    pointer ospriv;
 
324
NextAvailableClient(pointer ospriv)
371
325
{
372
 
    register int i;
373
 
    register ClientPtr client;
 
326
    int i;
 
327
    ClientPtr client;
374
328
    auReq data;
375
329
 
376
330
    i = nextFreeClientID;
377
331
    if (i == MAXCLIENTS)
378
 
        return (ClientPtr)NULL;
379
 
    clients[i] = client = (ClientPtr)xalloc(sizeof(ClientRec));
 
332
        return (ClientPtr) NULL;
 
333
    clients[i] = client = (ClientPtr) xalloc(sizeof(ClientRec));
380
334
    if (!client)
381
 
        return (ClientPtr)NULL;
 
335
        return (ClientPtr) NULL;
382
336
    InitClient(client, i, ospriv);
383
 
    if (!InitClientResources(client))
384
 
    {
385
 
        xfree(client);
386
 
        return (ClientPtr)NULL;
 
337
    if (!InitClientResources(client)) {
 
338
        xfree(client);
 
339
        return (ClientPtr) NULL;
387
340
    }
388
341
    data.reqType = 1;
389
342
    data.length = (sz_auReq + sz_auConnClientPrefix) >> 2;
390
 
    if (!InsertFakeRequest(client, (char *)&data, sz_auReq))
391
 
    {
392
 
        FreeClientResources(client);
393
 
        xfree(client);
394
 
        return (ClientPtr)NULL;
 
343
    if (!InsertFakeRequest(client, (char *) &data, sz_auReq)) {
 
344
        FreeClientResources(client);
 
345
        xfree(client);
 
346
        return (ClientPtr) NULL;
395
347
    }
396
348
    if (i == currentMaxClients)
397
 
        currentMaxClients++;
 
349
        currentMaxClients++;
398
350
    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
399
 
        nextFreeClientID++;
400
 
    return(client);
 
351
        nextFreeClientID++;
 
352
    return (client);
401
353
}
402
354
 
403
355
int
404
 
ProcInitialConnection(client)
405
 
    register ClientPtr client;
 
356
ProcInitialConnection(ClientPtr client)
406
357
{
407
358
    REQUEST(auReq);
408
 
    register auConnClientPrefix *prefix;
 
359
    auConnClientPrefix *prefix;
409
360
    int whichbyte = 1;
410
361
 
411
 
    prefix = (auConnClientPrefix *)((char *)stuff + sz_auReq);
 
362
    prefix = (auConnClientPrefix *) ((char *) stuff + sz_auReq);
412
363
    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
413
 
        return (client->noClientException = -1);
 
364
        return (client->noClientException = -1);
414
365
    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
415
 
        (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
416
 
    {
417
 
        client->swapped = TRUE;
418
 
        SwapConnClientPrefix(prefix);
 
366
        (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) {
 
367
        client->swapped = TRUE;
 
368
        SwapConnClientPrefix(prefix);
419
369
    }
420
370
    stuff->reqType = 2;
421
371
    stuff->length += (((int) prefix->nbytesAuthProto + 3) >> 2) +
422
 
                     (((int) prefix->nbytesAuthString + 3) >> 2);
423
 
    if (client->swapped)
424
 
    {
425
 
        swaps(&stuff->length, whichbyte);
 
372
            (((int) prefix->nbytesAuthString + 3) >> 2);
 
373
    if (client->swapped) {
 
374
        swaps(&stuff->length, whichbyte);
426
375
    }
427
376
    ResetCurrentRequest(client);
428
377
    return (client->noClientException);
429
378
}
430
379
 
431
380
int
432
 
ProcEstablishConnection(client)
433
 
    register ClientPtr client;
 
381
ProcEstablishConnection(ClientPtr client)
434
382
{
435
383
    char *reason, *auth_proto, *auth_string;
436
 
    register auConnClientPrefix *prefix;
 
384
    auConnClientPrefix *prefix;
437
385
    REQUEST(auReq);
438
386
 
439
 
    prefix = (auConnClientPrefix *)((char *)stuff + sz_auReq);
440
 
    auth_proto = (char *)prefix + sz_auConnClientPrefix;
 
387
    prefix = (auConnClientPrefix *) ((char *) stuff + sz_auReq);
 
388
    auth_proto = (char *) prefix + sz_auConnClientPrefix;
441
389
    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
442
390
    if (prefix->majorVersion != AuProtocolMajorVersion)
443
 
        reason = "Protocol version mismatch";
 
391
        reason = "Protocol version mismatch";
444
392
    else
445
 
        reason = ClientAuthorized(client,
446
 
                                  (unsigned short)prefix->nbytesAuthProto,
447
 
                                  auth_proto,
448
 
                                  (unsigned short)prefix->nbytesAuthString,
449
 
                                  auth_string);
450
 
    if (reason)
451
 
    {
452
 
        auConnSetupPrefix csp;
453
 
        char pad[3];
 
393
        reason = ClientAuthorized(client,
 
394
                                  (unsigned short) prefix->nbytesAuthProto,
 
395
                                  auth_proto,
 
396
                                  (unsigned short) prefix->
 
397
                                  nbytesAuthString, auth_string);
 
398
    if (reason) {
 
399
        auConnSetupPrefix csp;
 
400
        char pad[3];
454
401
 
455
 
        csp.success = auFalse;
456
 
        csp.lengthReason = strlen(reason);
457
 
        csp.length = ((int) csp.lengthReason + 3) >> 2;
458
 
        csp.majorVersion = AuProtocolMajorVersion;
459
 
        csp.minorVersion = AuProtocolMinorVersion;
460
 
        if (client->swapped)
461
 
            WriteSConnSetupPrefix(client, &csp);
462
 
        else
463
 
            (void)WriteToClient(client, sz_auConnSetupPrefix, (char *) &csp);
464
 
        (void)WriteToClient(client, (int)csp.lengthReason, reason);
465
 
        if (csp.lengthReason & 3)
466
 
            (void)WriteToClient(client, (int)(4 - (csp.lengthReason & 3)),
467
 
                                pad);
468
 
        return (client->noClientException = -1);
 
402
        csp.success = auFalse;
 
403
        csp.lengthReason = strlen(reason);
 
404
        csp.length = ((int) csp.lengthReason + 3) >> 2;
 
405
        csp.majorVersion = AuProtocolMajorVersion;
 
406
        csp.minorVersion = AuProtocolMinorVersion;
 
407
        if (client->swapped)
 
408
            WriteSConnSetupPrefix(client, &csp);
 
409
        else
 
410
            (void) WriteToClient(client, sz_auConnSetupPrefix,
 
411
                                 (char *) &csp);
 
412
        (void) WriteToClient(client, (int) csp.lengthReason, reason);
 
413
        if (csp.lengthReason & 3)
 
414
            (void) WriteToClient(client,
 
415
                                 (int) (4 - (csp.lengthReason & 3)), pad);
 
416
        return (client->noClientException = -1);
469
417
    }
470
418
 
471
419
    nClients++;
472
420
    client->sequence = 0;
473
 
    client->requestVector = 
474
 
        client->swapped ? AuSwappedProcVector : AuProcVector;
 
421
    client->requestVector =
 
422
            client->swapped ? AuSwappedProcVector : AuProcVector;
475
423
    return AuSendInitResponse(client);
476
424
}
477
425
 
478
426
void
479
 
MarkClientException(client)
480
 
    ClientPtr client;
 
427
MarkClientException(ClientPtr client)
481
428
{
482
429
    client->noClientException = -1;
483
430
}