Esempio n. 1
0
int asyncFileReadStart(AsyncFile *f, int fPosition, int count) {
  /* Start an asynchronous operation to read count bytes from the given file
	 starting at the given file position. The file's semaphore will be signalled when
	 the operation is complete. The client may then use asyncFileReadResult() to
	 find out if the operation succeeded and to get the data that was read. */

	AsyncFileState *state;
	OSErr err;

	if (!asyncFileValid(f)) return success(false);
	state = f->state;
	if (state->status == BUSY) return success(false);  /* operation in progress */

	/* allocate a new buffer if necessary */
	asyncFileAllocateBuffer(state, count);
	if (state->bufferPtr == nil) return success(false);  /* could not allocate buffer */

	asyncFileInitPB(state, fPosition);
	err = PBReadAsync(&state->pb);
	if (err != noErr) {
		state->status = IDLE;
		success(false);
		return 0;
	}
	return 0;
}
Esempio n. 2
0
// ====================== 1st thread
PRInt32 readWriteProc(PRFileDesc fd, void buf, PRUint32 bytes, IOOperation op)
{
        PRInt32 refNum; 
	OSErr err;
	int pbAsync_pb;
	int me_io_pending;

	// quick hack to allow PR_fprintf, etc to work with stderr, stdin, stdout 
	// note, if a user chooses "seek" or the like as an operation in another function 
	// this will not work 
	if (refNum >= 0 && refNum < 3)
	{
		switch (refNum)
		{
				case 0:
				  //stdin - not on a Mac for now
					err = paramErr;
					goto ErrorExit;
					break;
		                case 1: // stdout 
		                case 2: // stderr
					puts();
					break;
		}
		
		return (bytes);
	}
	else
	{
		PRBool  doingAsync = PR_FALSE;

		// 
		// Issue the async read call and wait for the io semaphore associated
		// with this thread.
		// Async file system calls *never* return error values, so ignore their
		// results (see <http://developer.apple.com/technotes/fl/fl_515.html>);
		// the completion routine is always called.
		//
		if (op == READ_ASYNC)
		{
		  //
		  //  Skanky optimization so that reads < 20K are actually done synchronously
		  //  to optimize performance on small reads (e.g. registry reads on startup)
		  //
			if ( bytes > 20480L )
			{
				doingAsync = PR_TRUE;
				{ __ESBMC_atomic_begin();
				if (__COUNT__ == 0) {
				  me_io_pending = PR_TRUE; // check for order violation
				  __COUNT__ = __COUNT__ + 1;
				} else {
				  assert(0);
				}
                 __ESBMC_atomic_end();
				}
				__START_ASYNC__ = True; // second thread can start
				(void)PBReadAsync(pbAsync_pb);
			}
			else
			{
				me_io_pending = PR_FALSE;
				
				err = PBReadSync(pbAsync_pb);
				if (err != noErr && err != eofErr)
					goto ErrorExit;
			}
		}
		else
		{
			doingAsync = PR_TRUE;
			me_io_pending = PR_TRUE;

			// writes are currently always async 
			(void)PBWriteAsync(pbAsync_pb);
		}
		
		if (doingAsync) {
			WaitOnThisThread(PR_INTERVAL_NO_TIMEOUT);
		}
	}
	
	if (err != noErr)
		goto ErrorExit;

	if (err != noErr && err != eofErr)
		goto ErrorExit;
	
	return; 

ErrorExit:
	_MD_SetError(err);
	return -1;
}