[Rxtx] to flush or not to flush, that is a question

Trent Jarvi tjarvi at qbang.org
Sat Sep 30 13:51:20 MDT 2006


Reading with no timeout and no threshold should block while there is no 
data assuming the port is not open with O_NONBLOCK at the C level. (we 
currently have a bug in w32 but the others should do this).

So from the JVM's perspective, this is a bit ugly as the thread is stuck 
in C libraries waiting for the (Native OS) kernel.

On Sat, 30 Sep 2006, Dr. Douglas Lyon wrote:

> Hi Joachim,
> Can you provide an example of the kind of blocked thread
> you are speaking about?
> Thanks!
>  - DL
>
>> Hello Doug,
>>
>> I'm not sure if your example was to prove that I'm right or wrong or 
>> just as an example. Your example is only on the Java level, the 
>> threads are not blocked, they are sleeping. To block a thread you 
>> have to drive it into a kernel call that does not return - the java 
>> VM implementation has no way of unwinding it from there.
>>
>> Best regards,
>> Joachim
>>
>> ---
>> Joachim Büchse
>> Softwarelösungen und Beratung
>> Hadlaubsteig 2
>> CH-8006 Zürich
>>
>>
>> On 29.09.2006, at 15:30, Dr. Douglas Lyon wrote:
>>
>>>  Hi All,
>>>  You may call System.exit(0) when threads are running or
>>>  blocked. The following example demonstrates this. The threads
>>>  never finish running, because System.exit(0) terminates the JVM.
>>>  Thanks!
>>>    - DL
>>>
>>>  public class ThreadTest {
>>>
>>>       public static void main(String args[]) {
>>>           int numberOfThreads = 5;
>>>           Thread t[] = new Thread[numberOfThreads];
>>>           System.out.println("Beginning thread test:");
>>>           for (int i=0; i < t.length; i++) {
>>>               t[i] = new Thread(new Hello(i));
>>>               t[i].start();
>>>           }
>>>           System.exit(0);
>>>       }
>>>  }
>>>
>>>
>>>  class Hello implements Runnable {
>>>       int i = 0;
>>>       int numberOfTimesRun = 0;
>>>       private static int totalNumberOfTimesRun = 0;
>>>
>>>       Hello(int id) {
>>>           i = id;
>>>       }
>>>       public static synchronized void incrementNumberOfTimes(){
>>>           totalNumberOfTimesRun++;
>>>       }
>>>       public void run() {
>>>           for (int j = 0; j < 10; j++) {
>>>               incrementNumberOfTimes();
>>>               System.out.println(
>>>                       "Hello #" + i +
>>>                       " numberOfTimesRun=" + numberOfTimesRun++ +
>>>                       "totalNumberOfTimesRun="+totalNumberOfTimesRun);
>>>               try {
>>>                   Thread.sleep(
>>>                           (int) (Math.random() * 1000));
>>>               } // try
>>>               catch (InterruptedException e) {
>>>                   e.printStackTrace();
>>>               }
>>>           } // for
>>>           System.out.println("Hello #" + i + " is done!");
>>>       }
>>>  }
>>>>  Hello Doug,
>>>>
>>>>  - A blocked thread does stop you calling System.exit().
>>>>  - System.exit() does not execute any garbage collection or java
>>>>  finalization, so file handles etc. may still be open. They are
>>>>  however cleaned up when the unix JVM process exits/uwinds.
>>>>  - A thread blocked in a kernel call will stop the java process from
>>>>  unwinding/exiting. The process is transformed into a zombie and holds
>>>>  on to it's resources until it can unwind.
>>>>
>>>>  1) You may spawn a thread to call close (time-out mechanism), however
>>>>  you should not if this is inside a finalize call.
>>>>  2) If the unix fd close never executes, you have a stale filehandle.
>>>>  However I never suggested it should not be called!
>>>>  3) "Exiting" the Java VM before unix fd close returns changes
>>>>  nothing. Returning from Port.close() in the case that it can not
>>>>  complete defers the unresolvable problem to the next person trying to
>>>>  use the unusable port. All other ports and the VM in general (GC,
>>>>  Finalization) should still work fine.
>>>>
>>>>  4) You don't know when the kernel has finished cleaning up after a
>>>>  unix fd close on a blocking fd. This is the same for IP sockets and
>>>>  files in Java. As no usefull information can be extracted from this,
>> >> I don't think it's an issue.
>>>>
>>>>  There are two informations you may want to know:
>>>>
>>>>  Q: When has all data been sent on a port?
>>>>  A: When Port.OutputStream.flush() returns, which may be called from
>>>>  Port.OutputStream.close()
>>>>
>>>>  Q: When can I reuse/open a Port?
>>>>  A: When Port.isCurrentlyOwned() returns false
>>>>  (CommPortOwnershipListener signals it)
>>>>
>>>>  Best regards,
>>>>  Joachim
>>>>
>>>>  ---
>>>>  Joachim Büchse
>>>>  Softwarelösungen und Beratung
>>>>  Hadlaubsteig 2
>>>>  CH-8006 Zürich
>> >>
>>>>
>>>>  On 29.09.2006, at 13:17, Dr. Douglas Lyon wrote:
>>>>
>>>>>   Hi Joachim,
>>>>>
>>>>>   As I understand it,
>>>>>   if close  blocks the invokers' thread of execution
>>>>>   it does not prevent another thread from calling
>>>>>   System.exit(0).
>>>>>   So, if we, as programmers, deem it OK to build our
>>>>>   own time-out for the close mechanism, I think this should be
>>>>>   possible, right?
>>>>>
>>>>>   On the other hand, if close never executes, the danger of
>>>>>   a serial port deadlock condition would seem to grow, right?
>>>>>
>>>>>   In the typical case, exiting before the close has completed
>>>>>   only defers the problem that the serial port cannot close, right?
>>>>>
>>>>>   Even worse, how will I know (inside of my own program) when
>>>>>   the close has completed? Will I need a call-back mechanism
>>>>>   (Listener) in
>>>>>   order to be notified of this?
>>>>>
>>>>>   Thanks!
>>>>>     - Doug
>>>>>
>>>>>
>>>>>>   My arguing must have been horribly unclear:
>>>>>>
>>>>>>   All I want is a distinction between Port.close() and
>>>>>>   Port.OutputStream.close().
>>>>>>   - Port.close() MUST NOT block (which means it can not flush).
>>>>>>   - Port.OutputStream.close() MAY flush.
>>>>>>
>>>>>>   Regarding you question: I think that OutputStream.flush() 
>>>>>>  should NOT
>>>>>>   timeout (and I'm 99% sure Gregg agrees;-). It MAY return with an
>>>>>>   exception if Port.close() is called. Turning the MAY into a "MUST"
>>>>>>   can complicate the API implementation (some OSs will not unwind a
>>>>>>   native tcdrain call and hence a handover mechanism / background
>>>>>>   thread has to be used). In RXTX this thread already exists so the
>>>>>>   RXTX implementation would not get systematicly more complicated.
>>>>>>
>>>>>>   Best regards,
>>>>>>   Joachim
>>>>>>
>>>>>>   ---
>>>>>>   Joachim Büchse
>>>>>>   Softwarelösungen und Beratung
>>>>>>   Hadlaubsteig 2
>>>>>>   CH-8006 Zürich
>>>>>>
>>>>>>
>>>>>>   On 29.09.2006, at 09:45, Dr. Douglas Lyon wrote:
>>>>>>
>>>>>>>    Hi All,
>>>>>>>    Let me see if I can summarize the discussion on flushing so far:
>>>>>>>
>>>>>>>    1. Manual Flush: A close is just a close vs.
>>>>>>>    2. Automatic Flush: A close is a flush and then a close.
>>>>>>>
>>>>>>>    On the one hand we can define a close for a serial port
>>>>>>>    so that it closes the serial port and has no other role. If
>>>>>>>    data has been left in the buffer, it will be lost unless a flush
>>>>>>>    is done explicitly.
>>>>>>>
>>>>>>>    While it is the case that this would seem to speed up
>>>>>>>    the close method, some might argue that the loss of data is
>>>>>>>    not good software engineering, thus impacting system 
>>>>>>>  reliability.
>>>>>>>    People will use:
>>>>>>>    sp.flush();
>>>>>>>    sp.close();
>>>>>>>    as a serial port idiom, if close does not automatically flush.
>>>>>>>
>>>>>>>    If flush does not precede close,
>>>>>>>    the possible loss of data should be taken into
>>>>>>>    account at the programmers' level, or it is a semantic error.
>>>>>>>
>>>>>>>    Others argue that a slow serial line will delay the delivery of
>>>>>>>    data for so long that the close will appear stalled.
>>>>>>>
>>>>>>>    Corner-point: The emperor has no close.
>>>>>>>
>>>>>>>    Suppose the serial device gets all stuffed up and data
>>>>>>>    cannot be delivered. In such a case, the close will never
>>>>>>>    finish with the flush and the serial port will never be 
>>>>>>>  released.
>>>>>>>
>>>>>>>    In such a case, other programs (and users) who need the resource
>>>>>>>    will be unable to access it.
>>>>>>>
>>>>>>>    Digression: once I went to a wedding on a boat where the head
>>>>>>>    was all stuffed up. Users were unable to flush and the
>>>>>>>    OutputStream never closed... :(
>>>>>>>
>>>>>>>    A serial port is a system wide resource for which many
>> >>>>> applications
>>>>>>>    may contend. Once it is assigned to a process, in theory, no 
>>>>>>>  other
>>>>>>>    application may usurp it.
>>>>>>>
>>>>>>>    Wont deadlock from unreleased resources impact system 
>>>>>>>  reliability?
>>>>>>>
>>>>>>>    So, on the one hand we adversely impact system reliability with
>>>>>>>    increased chance of deadlock, or adversely impact system
>>>>>>>   reliability
>>>>>>>    with increased chance of data loss.
>>>>>>>
>>>>>>>    To address the corner-point, the flush might need a time-out.
>> >>>>>  Perhaps
>>>>>>>    this can be computed as a function of the serial port data 
>>>>>>>  rate and
>>>>>>>    the
>>>>>>>    amount of data in the buffer.
>>>>>>>
>>>>>>>    Please let me know if I am missing something.
>>>>>>>
>>>>>>>    Thanks!
>>>>>>>      - Doug
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>    _______________________________________________
>>>>>>>    Rxtx mailing list
>>>>>>>    Rxtx at qbang.org
>>>>>>>    http://mailman.qbang.org/mailman/listinfo/rxtx
>>>>>>
>>>>>>
>>>>>>   _______________________________________________
>>>>>>   Rxtx mailing list
>>>>>>   Rxtx at qbang.org
>>>>>>   http://mailman.qbang.org/mailman/listinfo/rxtx
>>>>>
>>>>>
>>>>>   _______________________________________________
>>>>>   Rxtx mailing list
>>>>>   Rxtx at qbang.org
>>>>>   http://mailman.qbang.org/mailman/listinfo/rxtx
>>>>
>>>>
>>>>  _______________________________________________
>>>>  Rxtx mailing list
>>>>  Rxtx at qbang.org
>>>>  http://mailman.qbang.org/mailman/listinfo/rxtx
>>>
>>>
>>>  _______________________________________________
>>>  Rxtx mailing list
>>>  Rxtx at qbang.org
>>>  http://mailman.qbang.org/mailman/listinfo/rxtx
>>
>>
>> _______________________________________________
>> Rxtx mailing list
>> Rxtx at qbang.org
>> http://mailman.qbang.org/mailman/listinfo/rxtx
>
>
> _______________________________________________
> Rxtx mailing list
> Rxtx at qbang.org
> http://mailman.qbang.org/mailman/listinfo/rxtx
>


More information about the Rxtx mailing list