Start of port of AsyncIO library.
[AROS-Contrib.git] / workbench / libs / asyncio / src / WaitPacket.c
blobfd8c8b4aea0c7b50ce74b7a22970b28e90712e76
1 #include "async.h"
4 /* this function waits for a packet to come back from the file system. If no
5 * packet is pending, state from the previous packet is returned. This ensures
6 * that once an error occurs, it state is maintained for the rest of the life
7 * of the file handle.
9 * This function also deals with IO errors, bringing up the needed DOS
10 * requesters to let the user retry an operation or cancel it.
12 LONG
13 AS_WaitPacket( AsyncFile *file )
15 #ifdef ASIO_NOEXTERNALS
16 struct ExecBase *SysBase = file->af_SysBase;
17 struct DosLibrary *DOSBase = file->af_DOSBase;
18 #endif
19 LONG bytes;
21 if( file->af_PacketPending )
23 while( TRUE )
25 /* This enables signalling when a packet comes back to the port */
26 file->af_PacketPort.mp_Flags = PA_SIGNAL;
28 /* Wait for the packet to come back, and remove it from the message
29 * list. Since we know no other packets can come in to the port, we can
30 * safely use Remove() instead of GetMsg(). If other packets could come in,
31 * we would have to use GetMsg(), which correctly arbitrates access in such
32 * a case
34 Remove( ( struct Node * ) WaitPort( &file->af_PacketPort ) );
36 /* set the port type back to PA_IGNORE so we won't be bothered with
37 * spurious signals
39 file->af_PacketPort.mp_Flags = PA_IGNORE;
41 /* mark packet as no longer pending since we removed it */
42 file->af_PacketPending = FALSE;
44 bytes = file->af_Packet.sp_Pkt.dp_Res1;
46 if( bytes >= 0 )
48 /* packet didn't report an error, so bye... */
49 return( bytes );
52 /* see if the user wants to try again... */
53 if( ErrorReport( file->af_Packet.sp_Pkt.dp_Res2, REPORT_STREAM, file->af_File, NULL ) )
55 return( -1 );
58 /* user wants to try again, resend the packet */
59 AS_SendPacket( file,
60 file->af_Buffers[ file->af_ReadMode ?
61 file->af_CurrentBuf :
62 1 - file->af_CurrentBuf ] );
66 /* last packet's error code, or 0 if packet was never sent */
67 SetIoErr( file->af_Packet.sp_Pkt.dp_Res2 );
69 return( file->af_Packet.sp_Pkt.dp_Res1 );