Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 03/14/21 in all areas

  1. Vincent Parrett

    Waiting for multiple threads

    .NET has a nice construct for this, Cancellation Tokens. I created a delphi implementation a while ago https://github.com/VSoftTechnologies/VSoft.CancellationToken It's an abstraction around an event, where the calling thread owns the CancellationTokenSource (which has the cancel method) and the threads are passed the CancellationToken - which has the IsCancelled method you can interrogate, and the Handle that can be passed into api calls that take waithandles (like WaitforMultipleObjects). I have used the cancellation tokens in this library to make http calls cancellable https://github.com/VSoftTechnologies/VSoft.HttpClient It's also used in my https://github.com/VSoftTechnologies/VSoft.Awaitable async/await library (a abstraction over OmniThreadLibrary) All of the above are used in https://github.com/DelphiPackageManager/DPM - any methods that are potentially long running or might need to be cancelled take in an ICancellationToken - so for example in the command line tool, invocking Ctrl+C does this class procedure TDPMConsoleApplication.CtrlCPressed; begin FLogger.Information('Ctrl-C detected.'); FCancellationTokenSource.Cancel; end; That's all that's needed (from the outside at least) to cancel the task - and then in the tasks we pass the cancellation token function TInstallCommand.Execute(const cancellationToken : ICancellationToken) : TExitCode; begin // code deleted for brevity. if not FPackageInstaller.Install(cancellationToken, TInstallOptions.Default) then result := TExitCode.Error else result := TExitCode.OK; end; and in long running methods or tight loops for platform in platforms do begin if cancellationToken.IsCancelled then exit(false); ... or objHandles[0] := processInfo.hProcess; objHandles[1] := cancellationToken.Handle; { Wait for Something interesting to happen } waitRes := WaitForMultipleObjects(2, @objHandles, False, timeoutDuration);
  2. Anders Melander

    Profiler for Delphi

    It turns out the null GUID was what kept VTune from looking for the pdb file. VTune now loads my pdb file but doesn't resolve the addresses to source lines. I will probably have to populate the pdb with method information for that to work. Makes sense. I guess I'm not getting any sleep tonight
  3. Anders Melander

    Profiler for Delphi

    Not quite Game Over it seems. It appears that the Size being 1 is just because whomever wrote the linker has misunderstood the meaning of the field. 1 in this case means that there one entry, so I could replace the 1 with $1C and the entry would be valid. If I then assume that data in the debug directory is now valid then the one entry points to the .debug segment. I assume this segment contains the TDS debug data or something like (it starts with the TDS signature "FB09"). It's only present (for both 32- and 64-bit) if I link with debug info enabled. Now since this debug info isn't used anyway when profiling with VTune, I can just hijack the area occupied by it and store my IMAGE_DEBUG_TYPE_CODEVIEW structure there. This means that I won't have to deal with adding new sections and updating all the various offsets in the PE header. Should be doable with what I know so far. I have to some gardening to take care of now but I'll give it another go this evening. Stay (V)tuned...
  4. Dalija Prasnikar

    Waiting for multiple threads

    Not using global vars is good advice, but your particular advice here is wrong for several reasons. First, accessing global state (and changing it) is always a problem when it comes to thread safety, because one thread can change that state and interfere with the other using that same state. Think of global TFormatSettings variable. Having formatting functions that works directly with global setting is not thread safe because different threads can change settings as they please. On the other hands functions that use format settings passed as parameter are safe. But the crucial thing here is not passing as parameter alone, but what happens when you pass it in this particular case. TFormatSettings is a record and when you pass it as parameter function will get a local copy of the whole record. That is what it makes it safe. When you pass object instance as parameter, function will not get local copy of the object, just the reference. If the object is not thread safe and does not implement thread safety (synchronization) mechanisms that would allow safe access from multiple threads, then using parameter or global object directly is equally bad, and will not work. However, when it comes to synchronization objects, including TEvent, their whole purpose is to be shared between multiple threads. And if you need to orchestrate threads on application level, the only way you can do that is through global object. Yes, you can still write code in such manner that it does not access global object directly, but that code will not be "more thread safe", but more flexible and allows you to pass different TEvent instances to different threads that may have different purpose and possible different synchronization events. Using global locks, events and other synchronization objects is perfectly fine.
  5. Have you tried to see if there are any more exception or information debugging the IDE? Open some bpl then Run> Parameters... > Host Application "C:\Program Files (x86)\Embarcadero\Studio\21.0\bin\bds.exe" > Save > press F9 Then new instance of delphi will be created in debug mode, then you can reproduce the error in that delphi instance and you may have more information about the problem.
  6. Edwin Yip

    Waiting for multiple threads

    No problem. Human's language is sometimes ambiguous, the Pascal language is not, fortunately.
  7. pyscripter

    GetRegisteredPythonVersions for LINUX

    The PythonVersions unit is of little value in Linux, where there is no Registry and no registered Python versions. You need to manually provide the DLLName and DLLPath. You can use some code that searches possible file locations. For example in the Mac you can do, something like: {$ifdef MACOS} for N:= 5 to 9 do begin S:= Format('/Library/Frameworks/Python.framework/Versions/3.%d/lib/libpython3.%d.dylib', [N, N]); if FileExists(S) then exit(S); end; {$endif} In Debian Linux you can search for file locations such as: /usr/lib/x86_64-linux-gnu/libpython3.7m.so /usr/lib/x86_64-linux-gnu/libpython3.7m.so.1 /usr/lib/x86_64-linux-gnu/libpython3.7m.so.1.0 but it may vary by python distribution.
  8. Edwin Yip

    Waiting for multiple threads

    I think this the standard and easy way. But don't forget to pass the TEvent object to each threads, avoid accessing any global vars in anywhere including inside the a thread.
  9. vfbb

    Waiting for multiple threads

    This problem is very common because without proper care the threads end in a different order than the units. The rule to avoid this is: each unit that creates each thread has to guarantee that the thread it created will be canceled and completely terminated until the finalization of the unit. How to do this? There are several possibilities, I will quote one: 1) Create a way to cancel each thread (it is almost always possible through a simple Boolean + TEvent.SetEvent, but each case must be evaluated) 2) Create a unique TEvent to signal the end of the thread; Just run the thread code in a try finaly FFinishEvent.SetEvent; 3) At the end of the unit, cancel the thread, and give FFinishEvent.WaitFor;
  10. FredS

    Waiting for multiple threads

    I use a global TEvent that is set at shutdown, all my wait functions check that and all threads check it either through wait or in their execute methods.
  11. FredS

    Several F2084 Internal Error on Delphi 10.4.2

    This has been an issue on and off for a while now. Projects don't even need to be very large for it to happen and its better in one release then comes back with an update. Steps that helped, depending on Release version: Remove all source but your project's from accessible paths, GetIt does the opposite.. This means pre-compile Components in both Release and Debug Use a Clean.bat which removes all DCUs that may have been compiled using different directives. For me this was key, switching configuration outputs DCUs to a different subdir but for some reason Delphi failed to comprehend that. Eliminate all circular references, MMX works well for that.. Not something that would happen if Delphi was still built with Delphi.
  12. John Kouraklis

    Developer Express gave up on FMX

    Unless you have only Win apps and things like Win utils, FMX or more correctly cross-platform is the only way to go. The landscape in the market is vastly and rapidly changing and more platforms appear every other day. Unless you are an established large company, you can not afford to miss the opportunity of jumping into new markets quickly and with limited resources. We should not judge FMX's state and value based on what DevExpress says. I think their decision is more of a business one rather than a technical. Their clients are VCL develops and to me it is not a surprise that not many of them have adopted FMX. In fact, it is surprising they concluded there is no market for them. To me it seems very short-sighted understanding of the market. I am sure if they insisted, in 2-3 years their evaluation would be different. And I am also pretty sure when they started with the VCL suite, they had to iron out bugs, etc. But back then they were not the company they are now. Having said this, I have to mention here that I am not pleased with the way EMBA sees FMX either. I understand that most of Delphi clients are largely VLC developers. On the other hand, EMBA promotes Delphi as the one code base cross platform dev tool and yet they mostly focus on the introduction of new VLC products. This is a mess with their strategic priorities and every time I attend the webinars for new releases, I am disappointed to see they continue with the same approach. For example, they introduced a new TNumberBox---why is this not a FMX and VLC compoent? or the Control list?
  13. "Let's put dots into unit names, add some confusing matching logic for uses clauses that nobody understands and call that namespaces"
  14. Attila Kovacs

    Profiler for Delphi

    As I could not find anything measuring the InitUnits, and it has its reasons, I come up with this poor mans profiler: Two breakpoints is System.pas, one on TProc(P)(); in "procedure InitUnits;" and the other on the very next asm line: Then right-clink on the red bullets, "Breakpoint properties" -> "Advanced" On the first one: (actually you don't need the "Log result" here) On the second: (I have attached the InitHelper.pas to this post.) And just run the app. It will take a time to finish, then you can save the Events and process/investigate the output. Of course, the measured times are higher because of the debugger, but it gives a very good orientation for finding bottlenecks. To check the unit, place a conditional breakpoint on "I" somewhere. InitHelper.pas
  15. Darian Miller

    Profiler for Delphi

    The problem with NQS is lack of updates. The latest release is 1.63 from April 5, 2019. One minor version before that on Jan 8, 2019, two versions in 2017, and then it jumps to 2015. My renewal is due but it hasn't been updated since I purchased it so I haven't pulled the trigger on renewal. I originally purchased the TurboPower version many years ago and always preferred it over AQTime. The pricing for AQTime has always been higher and is now $1,900 per concurrent user. You can get a cheaper version at $600 but they don't allow you to run it on a VM. So the best price by far is NQS at about $310, especially if you can time it with a nice discount code.
  16. Tom F

    Profiler for Delphi

    I used AQTime for many years, but it seemed to me that SmartBear wasn't really interested in the Delphi market and their product suffered ... and was expensive. I more recently purchased Nexus Quality Suite and was very happy with it. Great tool, great support, great modern product: https://www.nexusdb.com/support/index.php?q=node/27156. As someone previously said, "You get what you pay for." NQS was well worth what we paid for it.
×