[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