• Welcome to Forum.Deepsoftware.Com. Please login or sign up.
 

HID component memory use discovery question

Started by MarkHolbrook, March 02, 2012, 10:10:39 pm

Previous topic - Next topic

MarkHolbrook

Hello Roman,

Thanks for your reply to the other thread.  I have written my service application as follows:

One MasterHID - This component is asked to update devices and I search it to find the scales I want to connect to.  This component is created once and left created.  It is never set to active.  It simply is used to locate the HID devices I'm interested in.

I then process the list found by MasterHID.  For each "scale" I detect I create a small object and dynamically create a HID component in that object for the device.  Once that is done I set it to active and the object handles the retrieval of the data from the scale.

This is all working nicely.  The scales are detected when the service starts and the data is coming across nicely.  So there are no issues so far with this design but there is one flaw...

It is possible that a user might unplug one of the scales.  What happens when this occurs is the HIDAfterReceive continues to be called but it looks like the internal driver or the link between the driver and the device is invalid.  The HIDAfterReceive doesn't crash or have any issues it just returns no data.  So I detect this and return an error code to my calling application that the scale has become disconnected.  Again so far this is all ok.

The flaw is that if the user then plugs the scale back in the created HID component does not automatically relink to the scale.  IE the existing HID component that was attached to that scale and its HIDAfterReceive do not relink.  The HIDAfterReceive continues to return no data.

I noticed in your HID example programs there is a WM_DEVICECHANGE message which you detect to get the HID component to rediscover the devices.   I tried implementing this message but from what I can see Service Applications do not get sent these messages. 

So I have two questions:

The first question is about the WM_DEVICECHANGE.  Is there some way to get a service application to see it?  If not I guessing I'd have to have my higher level app detect the message and send a message to the service.

The second question is on memory use.  If I keep the service exactly like described above my memory use for the service is stable.  IE it reaches a value and remains at the value even when the service is left to run for days.  This is what I need.

In order to combat the lack of WM_DEVICECHANGE message I tried having the service do a discovery... IE I have the masterHID component attempt to rediscover (update) HID devices and it looks through its list and if it already has a scale connect it just skips it, but if it sees a new scale or a scale that was connected and is now not getting data it reconnects it.

This approached solved my problem of needing a WM_DEVICE change.  Every 30 seconds or so the service would go out and try to find new scales and auto-reconnect those that had stopped functioning because the user unplugged them.  HOWEVER when this is in the code the memory use of the service grows continuously.  It starts at like 4.4m and after 6 hours it is 24m.  So clearly this approach is chewing up resources or not releasing memory.

So my second question is whether this is a bug or not and if so can it be fixed?  The basic sequence that is followed when we try to rediscover is to call:


  nrHIDMaster.Update;

    for c:=0 to pred(nrHIDMaster.DeviceCount) do
    begin
      nrHIDMaster.DeviceIndex := c;

      nrHIDMaster.UpdateDeviceDetails;

      // See if this is a scale we use
      if assigned(nrHIDMaster.HidDevice) then

Underneath this if we examine the manufacturer, type, etc.  If it is one of the scales we want then we try to find it if we already have it installed.  It is it installed already and working we simply skip it.  If it is new we add it.  If it is installed but not working... IE no data for a while we remove the small object and HID component and recreate them allowing them to relink with the scale.

So using this logic, nothing should be happening provided the scales are not removed and replugged.  My test when the memory went from 4.4m to 24m was this case.  Just left the scales plugged in.  So it seems like doing

nrHIDMaster.Update followed by the for loop actions is causing memory to be consumed.  Is there some way to force the HIDMaster to release its data?

So in summary two questions:

1) anyway to get WM_DEVICECHANGE at the service level.

2) anyway to get HID component to release memory it is consuming when periodically doing the loop above?

Thanks in advance

Roman Novgorodov

Hello

Thank you for detailed description.

My English is not so good as yours therefore I will be brief. See my answers below your lines:

QuoteSo in summary two questions:
1) anyway to get WM_DEVICECHANGE at the service level.


You need investigate and try RegisterDeviceNotification API function:
http://msdn.microsoft.com/en-us/library/aa363431%28VS.85%29.aspx

Quote
nrHIDMaster.Update followed by the for loop actions is causing memory to be consumed.  Is there some way to force the HIDMaster to release its data? ...
2) anyway to get HID component to release memory it is consuming when periodically doing the loop above?


If you see memory leak after periodically nrHIDMaster.Update() calls, it is a bug. We will check and try to fix.

Roman Novgorodov
DeepSoftware LLC
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

MarkHolbrook

Hi Roman,

Have you discovered anything on the memory leak during update?  Our client is anxious to know.

Mark

Roman Novgorodov

Hello

It seems like memory grows a little, but ReportMemoryLeaksOnShutdown flag does not reports about any leaks.
We need more time for test.

I recommend you to set nrHIDMaster.EnumFullMode := True and exclude call nrHIDMaster.UpdateDeviceDetails directly.

Roman Novgorodov
DeepSoftware LLC
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

MarkHolbrook

So do not call update but rather the mode you suggested instead?

Roman Novgorodov

Hello

You do not need call UpdateDeviceDetails() method. It requests details of selected device. You do not need it after set EnumFullMode property in True.

But you need call Update() method for refresh device list after WM_DEVICECHANGE message.

More correct code is following:

  nrHIDMaster.Update;
  for i :=0 to nrHIDMaster.DeviceCount - 1 do
    begin
       // See if this is a scale we use
       if TnrHidDevice(nrHIDMaster.Device[i]).SerialNumber = '111122233344' then OK!!!
    end; 


Roman Novgorodov
DeepSoftware LLC
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

MarkHolbrook

Ok but basically calling Update is chewing up memory slowly.   Unless that leak can be found or be isolated to be in a Windows routine we have no control over than I will have great difficultly certifying this code to work with our devices.  Some of our customers leave their computers running for 90 days.   So I kind of need an answer on whether this memory leak is something you can fix or if it is not in the nrComm library code.

M

Roman Novgorodov

Hello

Please describe how do you detect memory leak.
How many calls of Update method how much decreases memory?
We check Win7 task manager and XE2 built in memory manager options.

Can you create and upload here a simple application that shows memory leak?
This helps us to fix problem.

Roman Novgorodov
DeepSoftware LLC
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.