I have a simple application, which should send a single byte to a serial port once a minute. But sometimes, from some strange reason, it freezes somewhere in the WriteFile() function. Both sw and hw flow controls are turned off. I've googled some stuff about pending read operations performed from another threads, but I believe this is not a problem, because my app has single thread. Also, handle from CreateFile looks valid, so the port should not be used by any other applications. Have anybody suffered this?
If you google for the words writefile hangs, you'll find a number of discussions on this problem. Some leads are buffer overruns, sizing your buffer correctly, a defective COM port, clearing the status on error... Seems like there are plenty of things to try.
Another thing I would suggest is to use a communications library instead of calling the API directly, something like Async Professional (http://sourceforge.net/projects/tpapro/). Even if they add some overhead to your application, they might simplify your work and avoid a number of potential pitfalls...
Well, I'm using this library: http://lhdelphi.ic.cz/uploader/storage/ComDrv32.pas in Delphi 7, on Windows XP, but the component inside is just a wrapper around some Win API calls, CreateFile, WriteFile, etc.
Have you tried setting CommPortDriver.CheckLineStatus to true ("to prevent hangs when not device connected or device is OFF")? The source for the comdrv32.pas library contains that suggestion.
You can also try ComPort, which was neglected for some time but is now actively developed again.
Related
I use TIdHTTPServer in Delphi 11 to run a simple web server on a VPS.
It works great, except from time to time my app will start to use 100% of the CPU and keep this way forever, and I can't identify what is causing this.
When this happens, the server is still active and replying to requests, but very slowly. The only way to fix this is to force close the application and open it again.
I don't have any code to show, as my code is just generic responses using the OnCommandGet event of the TIdHTTPServer. This event will handle GET parameters on the URL and return something in the AResponseInfo.ContentText.
I know this is difficult, but any ideas about what I should hunt for to fix this?
We use TIdHttpServer quite a lot and have no problems with it. We use it in Delphi 10.3-10.4.2, but it’s not the reason for the problem. Programs work a few months without restarting.
From our experience we can say that problem of such unexpected behavior can be (in order of probability):
Code is not threadsafe. Event OnCommandGet run not in a main thread, so all access to global object/resources/etc must be done thru some kind of synchronization mechanism (locks, TEvent, synchronize, mutex, semaphore or other). If code does not use synchronization – it can broke logic, throw exceptions or do some other unexpected actions (like high CPU usage).
Connections count go over the limit. TIdHttpServer has properties like ListenQueue and MaxConnections. Can be that you make more requests that the server can handle. In this case your new requests wait until they can be handled by your code and it can make some additional CPU usage. To diagnose this – try to increment some internal variable at the start of your event and decrement it at the end. Make some service request to return this variable and you will know if all work correctly. Other similar situation – connection does not close after using the inside event and stay in memory, then you can go over limits too. Try to workaround properties TIdHttpServer.KeepAlive := false and TIdHttpServer.ReuseSocket := rsFalse.
Memory leaks. Try to set variable ReportMemoryLeaksOnShutdown := true and start the application, make a few requests and close it. If you’ll see a message with leaks – then you do something wrong, try to handle these objects in the right way. In production these small leaks can take a lot of RAM and Windows will dump part of memory into a swap-file, so your new requests will take more time to be processed.
Without an example, we can't say more.
The reason I ask this is widows do not support a good method to communicate between processes. So I want to create a DLL for a communications point between windows processes. A thread is owned by a process and cannot be given to another process.
Each thread has a stack of its own.
If a DLL is loaded (loadlibray) and a DLL function is called that asks windows for memory. Am I write to think the thread is still being owned by the same process and allocates memory into that same process.
So I’m thinking can I turn to assembly to reallocate a small memory block to another process. Create a critical section, copy the data over to another (already created) memory block and return to the original block to its original process with out up setting windows. Has any one done that before. Or is thier a better way.
Best regards,
Lex Dean.
I see other methods that mite be quite fast but I would like a very fast method that has little over head. Pipes and internet will obviously work but are not the best option yet simple to implement (thanks to offer such suggestions guys). I want to send quite a few 500 byte blocks at quite regular intervals sometimes. I like WM_COPYDATA because it looks fast, my biggest question that I have been looking all over the internet is:- GetCurrentProcess and DuplicateHandle to get the real handle. Finding the other process. And using messages to set up memory and then use WM_COPYDATA. I only need two messages a) the pointer and size b) the data has been copied.
I get my application process easy ‘GetCurrentProcess’ except it’s a pseudo handle, that’s always $FFFFFFE. I need the real process handle and no body on the internet gives an example of DuplicateHandle. That’s what’s got me stumped. Can you show me an example of DuplicateHandle as that’s what’s got me stumped?
I do not like turning to a form to get a handle as one application dose not always have a current form.
I do not like turning to a form to get a handle as one application dose not always have a current form.
In Delphi I have seen message sending with TSpeedButton to set up a simple fast communication methods between applications that most probably uses about 80 instructions I guess. And so I still thinking to think dll’s. The example Mads Elvheim sent is on that same line as what I already know.
I'm still willing to understand any other options of using my own *.Dll
Because my applications important to me can simply register/unregister on the *.DLL its own process rather than searching all the time to see if a process is current.
It’s how I manage memory with a *.DLL between process but I’m not told about.
To me DLL’s are not hard to implement to me as I already have one of my own in operation.
The real bottom line is access to windows to create a good option. As I’m very open to idea’s. Even the assembly instructions for between processes or a windows call. But I do not what to get court crashing windows ether by doing things illegal.
So please show an example of what you have done that is to my needs. That is fast and I’m interested as I most probably will use it anyway.
I have a very fast IPC (interprocess communication) solution based on named pipes. It is very fast and very easy to use (It hides the actual implementation from you. You just work with data packets). Also tested and proven. You can find the code and the demo here.
http://www.cromis.net/blog/downloads/cromis-ipc/
It also works across computers in the same LAN.
If your processes have message loops (with windows), you can send/receive serialized data with the WM_COPYDATA message: http://msdn.microsoft.com/en-us/library/ms649011(VS.85).aspx
Just remember that only the allocated memory for the COPYDATASTRUCT::lpData member is allowed to be read. Again, you can not pass a structure that has pointers. The data must be serialized instead. And the receiving side can only read this structure, it can not write to it. Example:
/* Both are conceptual windows procedures. */
/* For sending : */
{
...
TCHAR msg[] = _T("This is a test\r\n");
HWND target;
COPYDATASTRUCT cd = {0};
cd.lpData = _tcsdup(msg); // We allocate and copy a string, which is fine.
cd.cbData = _tcsclen(msg) + 1; //The size of our data. Windows needs to know this.
target = FindWindow(..); //or EnumProcesses
SendMessage(target, WM_COPYDATA, (LPARAM)hwnd, (WPARAM)&cd);
}
/* For receiving */
{
...
case WM_COPYDATA:
{
TCHAR* msg;
COPYDATASTRUCT* cb = (COPYDATASTRUCT*)wParam;
sender = FindWindow(..); //or EnumProcesses
//check if this message is sent from the window/process we want
if(sender == (HWND)lParam){
msg = _tcsdup(cb->ldData);
...
}
break;
}
}
Otherwise, use memory mapped files, or network sockets.
I currently use Mailslots in Delphi to do it and it is very efficient.
"Win32 DLLs are mapped into the address space of the calling process. By default, each process using a DLL has its own instance of all the DLLs global and static variables. If your DLL needs to share data with other instances of it loaded by other applications, you can use either of the following approaches:
•Create named data sections using the data_seg pragma.
•Use memory mapped files. See the Win32 documentation about memory mapped files."
http://msdn.microsoft.com/en-us/library/h90dkhs0(VS.80).aspx
You cannot share pointers between processes, they only make sense to the process that alloc'd it. You're likely to run into issues.
Win32 is not different from any other modern OS in this aspect. There are plenty IPC services at your disposal in Windows.
Try to describe, which task you want to solve - not the "...then I think that I need to copy that block of memory here...". It's not your task. Your customer didn't say you: "I want to transfer thread from one process to another".
I want to download a file from internet and I imagine this should be a simple task. Trying several different approaches I have found that each one has its own drawback.
The main issues are:
Application freezes until it downloads the file
Application freezes forever if the Internet connection is lost/server does not respond.
(details:
How to retrieve a file from Internet via HTTP?
The connection does not timeout while downloading file from internet )
So, finally I used the suggestions I got from several people to use "pro" libraries such as Indy. However, Indy is not much better than the pieces of code I have tried (but it is way much larger and difficult to maintain). While using Indy the application does not freezes only for short periods so it is still (somehow) usable. However, the application cannot be shut down until the download finishes (never if the Internet connections gets broken).
Other people reported the same problem: http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html
https://forums.embarcadero.com/thread.jspa?threadID=25199&tstart=90
So, there is some hacking I had to do to TIDAntiFreeze in order to make it work?
Also, the ConnectTimeout property is not recognized.
fIDHTTP := TIDHTTP.Create(NIL);
fIDHTTP.ConnectTimeout:=5000;
Should I drop Indy and return to original idea of downloading the file in a separate thread and end the thread when it does not respond (at least this way I get rid of 3rd party libraries)? There will be unforeseen side effects if I do this?
Using: Delphi 7, Indy 10.1.5 10.5 (probably).
Thanks
You probably need to use Indy the Indy way: using threads. Indy was specifically designed to work in blocking mode, because that's how most internet protocols work (example: with HTTP, at protocol level, you send a request, then you read the response. You don't send and receive at the same time). TIdAntiFreeze is supposed to help you use some Indy functionality without dealing with threads; I never used that because, at least conceptually, it's an ugly hack.
If you don't want to deal with threads then you should take a look at ICS - it was designed to be used in async mode, without threading. It doesn't need the equivalent of TIdAntiFreeze because it's not blocking. You start a download and you handle some events to get progress and completion notifications. ICS is just as well-known, professional and wildly used as Indy.
It's not too difficult to solve these sorts of problems. The first thing you have to do is make sure that you have properly handled error handling. If something fails then make sure everything cleans up properly. Beyond that make sure the downloading code is part of a separate thread. If there is any problem you can always terminate the thread from your main program. Here's the code (for downloading only, not the threading) which is working fine for me.
with TDownloadURL.Create(nil) do
try
URL := 'myurltodownload.com';
filename := 'locationtosaveto';
try
ExecuteTarget(nil);
except
result := false;
end;
if not FileExists(filename) then
result := false;
finally
clear;
free;
end;
Can any one tell me which is more stable? I know each has their own advantages and disadvantages. But which one is better for http, etc?
In my previous application I used indy9 but I wasn't satisfied with it, as I would sometimes get strange errors.
Can anyone recommend one?
I use Indy in a lot of projects. I used both 9 and 10 mainly as HTTP server and proxy. The projects get very intense traffic at times (HTTP). Indy never did let me down. It works very stable.
But I also had some "strange" situations where I had to dig deep to find the underlying problem. I also do not like the way Indy tends to handle a lot of things through exceptions. In general I like the ICS coding style more. But let me go to ICS.
ICS uses non-blocking sockets, while indy uses blocking. While non-blocking is ok and seems to be better at first sight, I found it irritating in a lot of situations. The problem is that the natural flow of the code gets lost because of the callback functions. This makes it harder to write procedural type of libraries. Furthermore I do not like how everything is handled through messages. For me it gets messy real quick when mixed with multithreading. And multithreading is mainstream these days.
So while I like the coding style and quality of the code in ICS, I prefer the simplicity of use and blocking mode of Indy. What you like more is up to you, but both libraries are mature and stable.
These are my two cents.
I also use both Indy and ICS.
Most of the time I prefer Indy because implementing sequential type of protocols with it is very easy (the request runs in it's own thread so you simply Read/Write to the connection, really easy). Using Indy requires solid knowledge of threading and synchronization. Unlike Runner I like how Indy uses Exceptions to handle "exceptional" stuff because it allows me to concentrate on the normal flow of the protocol (I use try-finally blocks to make sure I deallocate resources).
I also used ICS in a application where Indy simply failed: I used it for an application that implements an TCP/IP proxy. Using ICS was simpler because of it's non-blocking nature. I was able to "proxy" TCP/IP protocols that I know nothing about, so I have no idea how bytes would flow from one end to the other. Indy failed in that scenario because in Indy you're ether reading or you're writing, you can't do both at the same time. Using ICS to implement an sequential-type protocol is a bit of pain: you essentially need to use state-machine logic, brake the protocol in small bits, keep flags laying around so you know where you are in the protocol. An big plus: François Piette, the author of ICS, is active and very helpful on a number of forums and mailing list, and is very prompt to help with anything related to ICS.
For me, if I need to do something with TCP/IP, the decision path is very simple: Can it be done with Indy? Then it's Indy. If it can't be done with Indy then it'll be done with ICS!
I've used Indy 9 and 10 for TCP, HTTP and FTP with very few problems. ICS is a good choice, too. It's non blocking, which will change how you use it.
I haven't used it, but I've heard good things about Synapse, which is also blocking.
We test Indy10 IdTCPClient to receive video stream from remote server, it's OK. But when it's receiveing stream, the same time use it send some data to the server, after some minute, the received stream data began lost data bytes. We use sniffer tool to trace this problem, confirmed that IdTCPClient lost some bytes in receiveing stream.
So, we test Indy9.018, the same problem happend but a few times VS. Indy 10.
Remember that Indy is always in beta stage. Sometimes you need to work with night builds.
Which one is better really depends on specific use case, but I was unhappy with indy as an http client and ICS ended up being exactly what I needed it to be, with a lot less random quirks.
Note though that it is non blocking, so it's not just a drop in replacement.
I use Indy 9 for stable, released, production code to over 1 million users, and have never received any strange errors.
I'd say the answer depends on what you want to do with the internet. Indy is fine if you are prepared to get involved with understanding how it works, and is very capable. ICS is a different take on things, and I've used it effectively for many-connection systems. But for day to day "grab a file or send an email" type stuff, where you want to do a basic task, I pretty much always use Clever Components Internet Suite as you just create the component,
set the options, and it works. The suite is quite comprehensive, and gets useful updates.
I created a class that handles serial port asynchronously. I use it to communicate with a modem. I have no idea why, but sometimes, when I close my application, I get the Blue Screen and my computer restarts. I logged my code step by step, but when the BSOD appeared, and my computer restarted, the file into which I was logging data contained only white spaces. Therefore I have no idea, what the reason of the BSOD could be.
I looked through my code carefully and I found several possible reasons of the problem (I was looking for all that could lead to accessing unallocated memory and causing AV exceptions).
When I rethought the idea of asynchronous operations, a few things came to my mind. Please verify whether these are right:
1) WaitCommEvent() takes a pointer to the overlapped structure. Therefore, if I call WaitCommEvent() inside a function and then leave the function, the overlapped structure cannot be a local variable, right? The event mask variable and event handle too, right?
2) ReadFile() and WriteFile() also take references or pointers to variables. Therefore all these variables have to be accessible until the overlapped read or write operations finish, right?
3) I call WaitCommEvent() only once and check for its result in a loop, in the mean time doing other things. Because I have no idea how to terminate asynchronous operations (is it possible?), when I destroy my class that keeps a handle to a serial port, I first close the handle, and then wait for the event in the overlapped structure that was used when calling the WaitCommEvent() function. I do this to be sure that the thread that waits asynchronously for a comm event does not access any fields of my class which is destroyed. Is it a good idea or is it stupid?
try
CloseHandle(FSerialPortHandle);
if Assigned(FWaitCommEvent) then
FWaitCommEvent.WaitFor(INFINITE);
finally
FSerialPortHandle := INVALID_HANDLE_VALUE;
FreeAndNil(FWaitCommEvent);
end;
Before I noticed all these, most of the variables mentioned in point one and two were local variables of the functions that called the three methods above. Could it be the reason of the BSOD or should I look for some other mistakes in my code?
When I corrected the code, the BSOD stopped occuring, but It might be a coincidence. How do you think?
Any ideas will be appreciated. Thanks in advance.
I read the CancelIo() function documentation and it states that this method cancells all I/O operations issued by the calling thread. Is it OK to wait for the FWaitCommEvent after calling CancelIo() if I know that WaitCommEvent() was issued by a different thread than the one that calls CancelIo()?
if Assigned(FWaitCommEvent) and CancelIo(FSerialPortHandle) then
begin
FWaitCommEvent.WaitFor(INFINITE);
FreeAndNil(FWaitCommEvent);
end;
I checked what happens in such case and the thread calling this piece of code didn't get deadlocked even though it did not issue WaitCommEvent(). I tested in on Windows 7 (if it matters). May I leave the code as is or is it dangerous? Maybe I misunderstood the documentation and this is the reason of my question. I apologize for asking so many questions, but I really need to be sure about that.
Thanks.
An application running as a standard user should never be able to cause a bug check (a.k.a. BSOD). (And an application running as an Administrator should have to go well out of its way to do so.) Either you ran into a driver bug or you have bad hardware.
By default, Windows is configured to save a minidump in %SystemRoot%\minidump whenever a bug check occurs. You may be able to determine more information about the crash by loading the minidump file in WinDbg, configuring WinDbg to use the Microsoft public symbol store, and running the !analyze -v command in WinDbg. At the very least, this should identify what driver is probably at fault (though I would guess it's your modem driver).
Yes, you do need to keep the TOverlapped structure available for the duration of the overlapped operation. You're going to call GetOverlappedResult at some point, and GetOverlappedResult says it should receive a pointer to a structure that was used when starting the overlapped operation. The event mask and handle can be stored in local variables if you want; you're going to have a copy of them in the TOverlapped structure anyway.
Yes, the buffers that ReadFile and WriteFile use must remain valid. They do not make their own local copies to use internally. The documentation for ReadFile even says so:
This buffer must remain valid for the duration of the read operation. The caller must not use this buffer until the read operation is completed.
If you weren't obeying that rule, then you were likely reading into unreserved stack space, which could easily cause all sorts of unexpected behavior.
To cancel an overlapped I/O operation, use CancelIo. It's essential that you not free the memory of your TOverlapped record until you're sure the associated operation has terminated. Likewise for the buffer you're reading or writing. CancelIo does not cancel the operation immediately, so your buffers might still be in use even after you call it.