2

In my application, I have a ExecutorService of fixed size 1.

Now the thread calls some native code. Inside the native method, it gets blocked and waits for the OS events which needs to be dispatched. The issue is in graceful shutdown of the ExecutorService.

If I interrupt the thread, then thread still doesn't come out (Obviously). If I set the thread as daemon. Still it doesn't let the JVM to shutdown. The only working code I have is using System.exit which for obvious reason I do not intend to use. Any other way out?

ddmps
  • 4,350
  • 1
  • 19
  • 34
Jatin
  • 31,116
  • 15
  • 98
  • 163
  • Do you think try catch and end normal will work? – Madhu Mar 22 '13 at 11:07
  • 1
    @Madhu You can't throw an Exception (i.e try/catch anything) if it's stuck in native code - that's the problem. – ddmps Mar 22 '13 at 11:12
  • What native call is blocking? Can you artificially satisfy the wait? – Martin James Mar 22 '13 at 11:20
  • 'The only working code I have is using System.exit' What is the overriding reason for not using System.exit? – Martin James Mar 22 '13 at 11:21
  • @MartinJames Its a call to Mac Carbon framework function called `ReceiveNextEvent` which keeps dispatching OS events. The issue with System.exit is that- Firstly I need to free some native resources, and that can only I happen if I move out of native code. – Jatin Mar 22 '13 at 12:03
  • Oh - dunno Mac Carbon :(( Can't you, like, queue up an OS event? – Martin James Mar 22 '13 at 13:09
  • Ha, so did I. But I think progressed well except here. Queue up? I dont think it will solve the purpose as I need to dispatch the events and take necessary actions (which is currently happening) spontaneosly without delay. Issue is only with shutting it down. – Jatin Mar 22 '13 at 13:11

1 Answers1

3

The error lies in the native code that doesn't return, really. The only way to do it through the higher level java, as far as I know, is to stop() the thread - which is deprecated for several reasons.

To do this, you'd need to redesign to use an old-fashioned Thread instead of ExecutorService. You might as well do that as the size is fixed at 1 and therefore ExecutorService won't give you many advantages. As far as I see from your question it might seem like a viable option for you to use stop() if you do not keep any locks in the thread when you stop() it.

Edit:

According to Apple's developer guide (page 47), you can specify an EventTimeout when calling ReceiveNextEvent:

ReceiveNextEvent runs the low-level event loop, placing events as they occur into the event queue. The function returns when an event you specified occurs, or when the specified timeout is exceeded.

OSStatus ReceiveNextEvent(
UInt32 inNumTypes,
const EventTypeSpec *inList,
EventTimeout inTimeout,
Boolean inPullEvent,
EventRef *outEvent);

So, if I understand correctly setting a timeout when calling the native code will do the trick for you.

ddmps
  • 4,350
  • 1
  • 19
  • 34
  • Sorry, I meant `Thread.stop` only. An error. The thread doesn't come out and no ThreadDeath exception is thrown – Jatin Mar 23 '13 at 06:04