void xchgAndSwitchCoroutine(void *in_out_pPipeStreamState) { PipeStreamState *pPipeStreamState = (PipeStreamState *) in_out_pPipeStreamState; memxchg(&pPipeStreamState->mpCurrentCoroutineDescriptor, &pPipeStreamState->mpOtherCoroutineDescriptor, sizeof(CoroutineDescriptor*)); /* * Note that we just exchanged the two coroutine descriptors; that's why we * have this strange order. */ switchToCoroutine(pPipeStreamState->mpOtherCoroutineDescriptor, pPipeStreamState->mpCurrentCoroutineDescriptor); }
void* endianness_convert(void *in_out_pBuffer, size_t in_num) { uint8_t *ptr = (uint8_t *) in_out_pBuffer; size_t idx; for (idx = 0; idx < in_num/2; idx++) { memxchg(ptr+idx, ptr+in_num-1-idx, 1); } return in_out_pBuffer; }
void COROUTINE_KICKOFF_CALL geolocationCoroutine(void *in_pGarminUsbData) { GarminUsbData *pGarminUsbData = (GarminUsbData*) in_pGarminUsbData; DWORD theBytesReturned; BYTE* theBuffer = NULL; begin_of_geolocationCoroutine_loop: while (1) { DWORD theBufferSize = 0; DWORD readBytesCount = 0; theBytesReturned = ASYNC_DATA_SIZE; if (GarminCoroutineStateRequestToTerminate == pGarminUsbData->coroutineState) { pGarminUsbData->coroutineState = GarminCoroutineStateTerminated; return; } while (ASYNC_DATA_SIZE == theBytesReturned) { if (theBuffer != NULL) assert(_msize(theBuffer) == theBufferSize); if (!reallocBufferAndItsSizeAndDeleteIfFailure(&theBuffer, theBufferSize, ASYNC_DATA_SIZE)) { pGarminUsbData->coroutineState = GarminCoroutineStateErrorAllocation; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } if (!DeviceIoControl( pGarminUsbData->garminHandle, IOCTL_ASYNC_IN, 0, 0, theBuffer+theBufferSize, ASYNC_DATA_SIZE, &theBytesReturned, NULL)) { pGarminUsbData->coroutineState = GarminCoroutineStateErrorDeviceIoControl; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } theBufferSize += ASYNC_DATA_SIZE; readBytesCount += theBytesReturned; assert(readBytesCount <= theBufferSize); assert(_msize(theBuffer) == theBufferSize); } // So we have read the async packet if (!isPacketBufferOfCorrectSize((Packet_t*) theBuffer, readBytesCount)) { safe_free(&theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateErrorInvalidData; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } if (PacketType_USB_Protocol_Layer != ((Packet_t*) theBuffer)->mPacketType || Pid_Data_Available != ((Packet_t*) theBuffer)->mPacketId) { pGarminUsbData->coroutineState = GarminCoroutineStateOkSendingPossible; pGarminUsbData->pPacket = (Packet_t*) theBuffer; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); safe_free(&theBuffer); continue; } /* * We got a signal package before that we haven't deleted */ assert(theBuffer != NULL); safe_free(&theBuffer); /* * If this was a small "signal" packet, read a real * packet using ReadFile */ theBuffer = (BYTE*) malloc(MAX_BUFFER_SIZE); if (theBuffer == NULL) { pGarminUsbData->coroutineState = GarminCoroutineStateErrorAllocation; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } if (!ReadFile(pGarminUsbData->garminHandle, theBuffer, MAX_BUFFER_SIZE, &theBytesReturned, NULL)) { safe_free(&theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateErrorReadFile; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } if (theBytesReturned == 0) { safe_free(&theBuffer); goto begin_of_geolocationCoroutine_loop; } if (!isPacketBufferOfCorrectSize((Packet_t*) theBuffer, theBytesReturned)) { safe_free(&theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateErrorInvalidData; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } { BYTE *theNextBuffer = NULL; theNextBuffer = (BYTE*) malloc(MAX_BUFFER_SIZE); if (theNextBuffer == NULL) { safe_free(theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateErrorAllocation; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } /* * Keep reading packets * until the driver returns a 0 size buffer. */ while (1) { if (!ReadFile(pGarminUsbData->garminHandle, theNextBuffer, MAX_BUFFER_SIZE, &theBytesReturned, NULL)) { safe_free(&theNextBuffer); safe_free(&theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateErrorReadFile; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } if (theBytesReturned == 0) { safe_free(&theNextBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateOkSendingPossible; pGarminUsbData->pPacket = (Packet_t*) theBuffer; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); safe_free(&theBuffer); break; } if (!isPacketBufferOfCorrectSize((Packet_t*) theNextBuffer, theBytesReturned)) { safe_free(&theNextBuffer); safe_free(&theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateErrorInvalidData; pGarminUsbData->pPacket = NULL; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); return; } pGarminUsbData->coroutineState = GarminCoroutineStateOkSendingNotPossible; pGarminUsbData->pPacket = (Packet_t*) theBuffer; switchToCoroutine(pGarminUsbData->pGeolocationCoroutine, pGarminUsbData->pMainCoroutine); if (GarminCoroutineStateRequestToTerminate == pGarminUsbData->coroutineState) { safe_free(&theNextBuffer); safe_free(&theBuffer); pGarminUsbData->coroutineState = GarminCoroutineStateTerminated; return; } memxchg(&theBuffer, &theNextBuffer, sizeof(BYTE*)); } } } }
void UndoRedo(bool bRedo){ // exchange memory memxchg(Array,Prev,Size); }