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

View File

@ -260,25 +260,25 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
uint16 index, uint16 length, void *data, size_t dataLength,
size_t *actualLength)
{
transfer_result_data transferResult;
transferResult.notify_sem = create_sem(0, "usb send request notify");
if (transferResult.notify_sem < B_OK)
transfer_result_data *transferResult = (transfer_result_data *)malloc(sizeof(transfer_result_data));
transferResult->notify_sem = create_sem(0, "usb send request notify");
if (transferResult->notify_sem < B_OK)
return B_NO_MORE_SEMS;
status_t result = QueueRequest(requestType, request, value, index, length,
data, dataLength, SendRequestCallback, &transferResult);
data, dataLength, SendRequestCallback, transferResult);
if (result < B_OK) {
delete_sem(transferResult.notify_sem);
delete_sem(transferResult->notify_sem);
return result;
}
// 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
// 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"));
delete_sem(transferResult.notify_sem);
delete_sem(transferResult->notify_sem);
if (actualLength)
*actualLength = 0;
@ -286,11 +286,13 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
return B_TIMED_OUT;
}
delete_sem(transferResult.notify_sem);
delete_sem(transferResult->notify_sem);
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;
transferResult->status = status;
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);
}
}