Changing from a stack allocated result struct to a heap allocated one. This removes the possibility that a timed out transfer that later still triggers the callback writes into invalid stack space.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20004 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2007-01-29 01:18:17 +00:00
parent a94a8358e8
commit 4771489e89
+16 -11
View File
@@ -260,25 +260,25 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
uint16 index, uint16 length, void *data, size_t dataLength, uint16 index, uint16 length, void *data, size_t dataLength,
size_t *actualLength) size_t *actualLength)
{ {
transfer_result_data transferResult; transfer_result_data *transferResult = (transfer_result_data *)malloc(sizeof(transfer_result_data));
transferResult.notify_sem = create_sem(0, "usb send request notify"); transferResult->notify_sem = create_sem(0, "usb send request notify");
if (transferResult.notify_sem < B_OK) if (transferResult->notify_sem < B_OK)
return B_NO_MORE_SEMS; return B_NO_MORE_SEMS;
status_t result = QueueRequest(requestType, request, value, index, length, status_t result = QueueRequest(requestType, request, value, index, length,
data, dataLength, SendRequestCallback, &transferResult); data, dataLength, SendRequestCallback, transferResult);
if (result < B_OK) { if (result < B_OK) {
delete_sem(transferResult.notify_sem); delete_sem(transferResult->notify_sem);
return result; return result;
} }
// the sem will be released in the callback after the result data was // the sem will be released in the callback after the result data was
// filled into the provided struct. use a 5 seconds timeout to avoid // filled into the provided struct. use a 5 seconds timeout to avoid
// hanging applications. // hanging applications.
if (acquire_sem_etc(transferResult.notify_sem, 1, B_RELATIVE_TIMEOUT, 5000000) < B_OK) { if (acquire_sem_etc(transferResult->notify_sem, 1, B_RELATIVE_TIMEOUT, 5000000) < B_OK) {
TRACE_ERROR(("USB ControlPipe: timeout waiting for queued request to complete\n")); TRACE_ERROR(("USB ControlPipe: timeout waiting for queued request to complete\n"));
delete_sem(transferResult.notify_sem); delete_sem(transferResult->notify_sem);
if (actualLength) if (actualLength)
*actualLength = 0; *actualLength = 0;
@@ -286,11 +286,13 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
return B_TIMED_OUT; return B_TIMED_OUT;
} }
delete_sem(transferResult.notify_sem); delete_sem(transferResult->notify_sem);
if (actualLength) if (actualLength)
*actualLength = transferResult.actual_length; *actualLength = transferResult->actual_length;
return transferResult.status; result = transferResult->status;
free(transferResult);
return result;
} }
@@ -301,7 +303,10 @@ ControlPipe::SendRequestCallback(void *cookie, status_t status, void *data,
transfer_result_data *transferResult = (transfer_result_data *)cookie; transfer_result_data *transferResult = (transfer_result_data *)cookie;
transferResult->status = status; transferResult->status = status;
transferResult->actual_length = actualLength; transferResult->actual_length = actualLength;
release_sem(transferResult->notify_sem); if (release_sem(transferResult->notify_sem) < B_OK) {
// the request has timed out already - cleanup after us
free(transferResult);
}
} }