Hi,
I have a sample application that registers for keyboard and mouse hooks and does simply a system.out when one is received. Once enabled, everything works fine, however if you dont touch the mouse and keyboard for a few minutes eventually you get some callbacks for events that have not occured. Is there any explaination as to why this happens or could it be a bug?
Thanks,
Alex Kritikos
Hi Alex,
Frankly speaking, this is first such case in my practice. May be this is really because of bugs... real ones? Joking of course ![]()
If these were mouse events and you have an optical mouse, then probably it can be explained by fact that some optical mouse can produce some random 'mouse move' events even if nobody touches them. We've just discussed here this guess and many of us saw such strange behavior. Could it be the cause in your case?
-Serge
Hi Serge,
i thought about that too but unfortunately not the case. I have tested with a ball mouse and i get the same plus i also receive keyboard events. I also thought that maybe some other applications where generating mouse events / keyboard events but i tested running only the jniwrapper app. We are using the hooks to try and monitor user status (away/active) in a chat system so when there is activity we disable the hooks and when there isnt we reenable them. When this happens we seem to randomly receive events. To reproduce i have written a simple application that prints with a timestamp when an event is received and has a thread that every 10 seconds toggles the hooks. This is my output (without touching the mouse obviously)
Got action event
Fri Feb 09 15:17:57 EET 2007-Mouse Coordinates: X=151, Y=268
Fri Feb 09 15:18:07 EET 2007 Toggled hooks
Fri Feb 09 15:18:17 EET 2007 Toggled hooks
Fri Feb 09 15:18:27 EET 2007 Toggled hooks
Fri Feb 09 15:18:37 EET 2007 Toggled hooks
Fri Feb 09 15:18:47 EET 2007 Toggled hooks
Fri Feb 09 15:18:57 EET 2007 Toggled hooks
Fri Feb 09 15:18:57 EET 2007-Mouse Coordinates: X=151, Y=268
Fri Feb 09 15:19:07 EET 2007 Toggled hooks
Fri Feb 09 15:19:17 EET 2007 Toggled hooks
Fri Feb 09 15:19:17 EET 2007-Mouse Coordinates: X=151, Y=268
Fri Feb 09 15:19:27 EET 2007 Toggled hooks
Fri Feb 09 15:19:37 EET 2007 Toggled hooks
Fri Feb 09 15:19:37 EET 2007-Mouse Coordinates: X=151, Y=268
Fri Feb 09 15:19:47 EET 2007 Toggled hooks
Fri Feb 09 15:19:57 EET 2007 Toggled hooks
Fri Feb 09 15:20:07 EET 2007 Toggled hooks
Fri Feb 09 15:20:17 EET 2007 Toggled hooks
Fri Feb 09 15:20:18 EET 2007-Mouse Coordinates: X=154, Y=223
Fri Feb 09 15:20:18 EET 2007-Mouse Coordinates: X=154, Y=223
Fri Feb 09 15:20:18 EET 2007-Mouse Coordinates: X=154, Y=223
Fri Feb 09 15:20:18 EET 2007-Mouse Coordinates: X=154, Y=223
Fri Feb 09 15:20:20 EET 2007-Mouse Coordinates: X=154, Y=223
Fri Feb 09 15:20:27 EET 2007 Toggled hooks
If you want i could send you the source from this test.
Alex
Hi Alex,
Yes, please attach your example so we can test it. Because I was unable to reproduce this problem using our examples.
Also, is this problem reproducible on some particular computer only or you could reproduce it on different machines? What version of JNIWrapper do you use?
-Serge
Hi Serge,
I am using JNIWrapper 3.5 and the problem occurs on more than one machine...
I attach the source of the app, all you need to do is click once on enable hooks then let the thread do the toogling, back away and watch the console....
Thanks,
Alex Kritikos
my-Channels
Thanks Alex, I was able to reproduce the problem several times, but I got only sporadic mouse events. I think this may happen because of multiple install/uninstall operations. Theoretically it should not happen if you install hooks only once.
Anyway, I will investigate this problem and let you know the solution.
-Serge
Hi Serge,
do you have any workaround to suggest or any other update on this issue?
Thanks,
Alex Kritikos
Hi Alex,
Please try the attached WinPack library and let me know results.
-Serge
Hi Alex,
I'm just wondering if you had a chance to test this update. I would greatly appreciate your feedback on it.
-Serge
Hi Serge,
apologies for the delay in responding to you. The winpack jar you supplied seems to fix the problem so far. I was wondering if this is *production *ready and whether it can be used with a JNIWrapper 3.5 jar file.
Thanks,
Alex Kritikos
my-Channels
Hi Alex,
Thanks for the information, I'm glad it helped.
This update is actually WinPack 3.5 plus several fixes (including the fix Hooks API) and improvements that we made to make WinPack "Vista ready". We are planning to release WinPack 3.6 soon. So I think you can use it along with JNIWrapper 3.5 without any problem. Should any problem appear just let us know.
-Serge
Hi Serge,
may i should have opened a new thread for this but instead i am resume the old one as this is related.... We have been using JNIwrapper 3.5 with Winpack 3.6 since we last spoke in production. We have a class that extends thread and is a HookEventListener. The class has a runloop which based on the hook events received calculates a user idle status (this is a chat system) and potentially installs/uninstalls hooks / sends status events. In the past this was receiving events even though there was no activity, something you found had to do with winpack hooks being installed / uninstalled too often and you gave us the 3.6 version of winpack to use instead which we have been so far. The reason we are uninstalling the hooks when we know there is user activity is that its an unnecessary overhead for the application and we had seen CPU spikes when it was happening.
When we receive an onHookEvent callback, the runloop may be still busy going through the cycle before the callback so we merely queue the OnHookEvent so that we process it asynchronously. What we have seen is that due to a timing problem the mechanism gets into a lock where events are not processed, but the problem is that the activethread count increases a lot very fast causing our application to spin. A thread dump showed the following: (only relevant threads shown)
"Thread-198" daemon prio=6 tid=0x0aca3e90 nid=0xb3c runnable 0x0e82f000..0x0e82fae8
at com.jniwrapper.Function.invokeCFunc(Native Method)
at com.jniwrapper.FunctionCall.a(SourceFile:121)
at com.jniwrapper.FunctionCall.call(SourceFile:34)
at com.jniwrapper.Function.invoke(SourceFile:162)
at com.jniwrapper.Function.invoke(SourceFile:198)
at com.jniwrapper.win32.system.EventObject.waitFor(EventObject.java:56)
at com.jniwrapper.win32.hook.Hook$HookEventLoop.run(Hook.java:343)
at java.lang.Thread.run(Unknown Source)
"ChatDock - Activity Monitor Thread" daemon prio=6 tid=0x0ad14f78 nid=0x924 in Object.wait() 0x0ef2f000..0x0ef2fd68
at java.lang.Object.wait(Native Method)
- waiting on <0x03621718> (a java.lang.Thread) at java.lang.Thread.join(Unknown Source) - locked <0x03621718> (a java.lang.Thread) at java.lang.Thread.join(Unknown Source) at com.jniwrapper.win32.hook.Hook.uninstall(Hook.java:277) at com.pcbsys.chat.gui.ActivityMonitorThread.uninstall(Unknown Source) - locked <0x034a3bd0> (a com.pcbsys.chat.gui.ActivityMonitorThread)
at com.pcbsys.chat.gui.ActivityMonitorThread.run(Unknown Source)
"ChatDock - Activity Event Q" daemon prio=6 tid=0x0ace6720 nid=0xe2c waiting for monitor entry 0x0ee6f000..0x0ee6fa68
at com.pcbsys.chat.gui.ActivityMonitorThread.a(Unknown Source)
- waiting to lock <0x034a3bd0> (a com.pcbsys.chat.gui.ActivityMonitorThread)
at com.pcbsys.foundation.uj.h(Unknown Source)
at com.pcbsys.foundation.fk.run(Unknown Source)
The activity monitor thread is the class with the runloop which is also a hook event listener. The Activity Event Q is the hook event queue which uses a thread pool to provide callbacks to the queued object processor which is again the activity monitor thread.
Sometimes we see a lot of threads like Thread-198 and sometimes just one but the CPU spikes very high in both cases. What i am wondering is whether the queueing of HookEventObjects corresponds to a 1-1 mapping in threads you create to serve the native call. Is that the case?
Also in the above stack trace part, we see that the activity monitor thread decided in its runloop that it should uninstall the hook, however the call is locked waiting for the event thread to die in the join call (this must be the Thread-198 in the dump). That thread is also blocked waiting for the native call to finish with an indefinite wait time...
Can you please clarify this is the case and provide with any suggestions to prevent this..
Thanks,
Alex Kritikos
my-Channels
Any updates on this?
Message was edited by: Alex Kritikos
re opened issue as still having problems with it
Hi Alex,
Sorry for the delay in getting back to you.
From the description that you have provided it seems that this problem depends somehow on event notification mechanism (using the EventObject class) from native library to Java side. Actually you can find the details of this implementation in Hook.HookEventLoop class, which is available in WinPack distribution archive.
In order to find and fix this problem I will probably need the complete test application that reproduces this issue. Can you please provide such example?
Alternatively, I think you can try attached LowLevelMouseHookSample.java example which implements low level mouse hook using JNIWrapper without Hook API from WinPack library. Please note that this example is not included to WinPack examples yet. We will add it to WinPack in the next version along with LowLevelKeyboardHookSample.java.
Btw, did you try Hook.FOREGROUNDIDLE hook in order to determine idle state?
-Serge
Hi Serge,
thanks for your response. I am in agreement about the area that may be causing the problem. On our side we are trying to change our logic so that for example:
1. When the hooks are uninstalled, any hook events in our queue are ignored as they must have got queued before the uninstall call
2. Reducing our event queue high watermark to a value such as 5, we dont need to queue any more events.
3. Should we reach HWM we suspend the queue from further queuing events
Regarding the Hook.FOREGROUNDIDLE no we havent tried it but we have tried the timer based IdleListener example which works similarly to what we have done as far as detecting idleness but we still need to go lower level in order to detect the end of idleness (through hooks) so its a no go for us.
Regarding the code that reproduces the problem, its very hard to provide you with that without either spending a lot of time rewriting quite a few of our propriertry foundation classes or giving you access to proprietry source code. So unfortunately we will have to keep trying to find a fix as we are.
Finally i will check your attached source to see if it can help us at all.
Many thanks,
Alex Kritikos
my-Channels