Serial Library: Clarity needed on SerialEvent() comment

Hello folks!

Can someone help provide clarity on a comment in the Serial library?

The comment is here:
processing/java/libraries/serial/src/processing/serial/Serial.java at master · processing/processing · GitHub

and states:

// serialEvent() is invoked in the context of the current (serial) thread
// which means that serialization and atomic variables need to be used to
// guarantee reliable operation (and better not draw() etc…)
// serialAvailable() does not provide any real benefits over using
// available() and read() inside draw - but this function has no
// thread-safety issues since it’s being invoked during pre in the context
// of the Processing applet

What does that mean?

I can use available() and read() inside draw instead of serialEvent() interchangeably in most cases.
Does this suggest that that is safer to do so and avoids thread-safety issues?

:)

hi glv,

may be i’m wrong but i understand it like that:

serialEvent() come from a thread, so one can be worry it is asynchronous and run in parallel to draw(), (eg writing to serial in draw() while some code read from serial at same time in serialEvent())

but as it is processed during pre (i guess pre-draw() ) we can’t mess with simultaneous access to serial port.

to me, it means you’re right you can use available() and read() inside draw instead of serialEvent() interchangeably :thinking:

(witch is a little bit strange, we can imagine a low framerate sketch but listening as fast as possible )

edit:
not sure, i think this is true if you still check serialAvailable() in serialEvent()

It is not clear to me what serialAvailable() is referring to.

A search for serialAvailable in the GitHub page comes up with:

Method serialAvailableMethod;
volatile boolean invokeSerialAvailable = false;
serialAvailableMethod = findCallback("serialAvailable");
serialEventMethod = findCallback("serialEvent");
serialAvailableMethod = findCallback("serialAvailable");
 public void pre() {
    if (serialAvailableMethod != null && invokeSerialAvailable) {
      invokeSerialAvailable = false;
      try {
        serialAvailableMethod.invoke(parent, this);
      } catch (Exception e) {
        System.err.println("Error, disabling serialAvailable() for "+port.getPortName());
        System.err.println(e.getLocalizedMessage());
        serialAvailableMethod = null;
      }
    }
  }

I also found this:
P3D crash with serialEvent · Issue #5398 · processing/processing · GitHub

Which states and refers to my quote:

We discussed this pitfall when the Serial library was re-written, see [here]
(processing/java/libraries/serial/src/processing/serial/Serial.java at master · processing/processing · GitHub).

@MazeArt Could you try changing serialEvent to (the undocumented) serialAvailable, and check if this works? (If it does, then this was indeed the issue, and you might want to then move all your code inside draw and make use of available(), instead of serialEvent).

Interesting!

:)

Everything is in the buffer so as long as you have a while() in there you are good to go!

You may receive multiple myStrings in that while() loop so have to buffer and process on the receiving end also.

I did not have any issues with it as long as you can receive everything and process it in each frame.

void draw() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil(lf);
    // Your code
    }
  }
}

:)