|
@@ -19,6 +19,9 @@ function ShellFolderParseDisplayNameWithTimeout(
|
|
|
function DestinationListBeginList(
|
|
|
DestinationList: ICustomDestinationList; var pcMaxSlots: UINT; const riid: TIID; out ppv: Pointer; Timeout: Integer): HRESULT;
|
|
|
|
|
|
+var
|
|
|
+ TimeoutShellOperations: Boolean = True;
|
|
|
+
|
|
|
implementation
|
|
|
|
|
|
uses
|
|
@@ -101,26 +104,33 @@ var
|
|
|
begin
|
|
|
// When running from IDE, it triggers starting/exiting the thread taking ages.
|
|
|
// So in IDE we revert to single-thread approach.
|
|
|
-{$IFDEF IDE}
|
|
|
- OperationEvent(Operation);
|
|
|
- Result := True;
|
|
|
-{$ELSE}
|
|
|
- // Have to start new thread for each request. When shared thread is used, it eventually hangs.
|
|
|
- // Most probably do to the fact that we violate COM threading model.
|
|
|
- // So using a new thread for each request, is only a hack that happens to work by pure luck.
|
|
|
- // We may want to use shared thread at least for COM-free operations, like SHGetFileInfo.
|
|
|
- Thread := TOperationWithTimeoutThread.Create(Operation, OperationEvent);
|
|
|
- Thread.Resume;
|
|
|
- Result := Thread.WaitFor(MSecsPerSec);
|
|
|
- if Result then
|
|
|
+{$IFNDEF IDE}
|
|
|
+ if not TimeoutShellOperations then
|
|
|
+{$ENDIF}
|
|
|
begin
|
|
|
- Thread.Free;
|
|
|
+ OperationEvent(Operation);
|
|
|
+ Result := True;
|
|
|
end
|
|
|
+{$IFNDEF IDE}
|
|
|
else
|
|
|
begin
|
|
|
- // There's a chance for memory leak, if thread is terminated
|
|
|
- // between WaitFor() and this line
|
|
|
- Thread.FreeOnTerminate := True;
|
|
|
+ // Have to start new thread for each request. When shared thread is used, it eventually hangs.
|
|
|
+ // Most probably do to the fact that we violate COM threading model.
|
|
|
+ // So using a new thread for each request, is only a hack that happens to work by pure luck.
|
|
|
+ // We may want to use shared thread at least for COM-free operations, like SHGetFileInfo.
|
|
|
+ Thread := TOperationWithTimeoutThread.Create(Operation, OperationEvent);
|
|
|
+ Thread.Resume;
|
|
|
+ Result := Thread.WaitFor(MSecsPerSec);
|
|
|
+ if Result then
|
|
|
+ begin
|
|
|
+ Thread.Free;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ // There's a chance for memory leak, if thread is terminated
|
|
|
+ // between WaitFor() and this line
|
|
|
+ Thread.FreeOnTerminate := True;
|
|
|
+ end;
|
|
|
end;
|
|
|
{$ENDIF}
|
|
|
end;
|