Error waited 5000ms

edited December 2016 in Library Questions

Hello I quite often have this error for quite a while since I'm using the librairy Beads (wich is up on date).

Here is the error I get java.lang.RuntimeException: Waited 5000ms for: <439eac3d, 4d595a3e>[count 2, qsz 0, owner <main-FPSAWTAnimator#00-Timer0>] - <main-FPSAWTAnimator#00-Timer0-FPSAWTAnimator#00-Timer1> at processing.opengl.PSurfaceJOGL$2.run(PSurfaceJOGL.java:459) at java.lang.Thread.run(Thread.java:745) java.lang.RuntimeException: Waited 5000ms for: <439eac3d, 4d595a3e>[count 2, qsz 0, owner <main-FPSAWTAnimator#00-Timer0>] - <main-FPSAWTAnimator#00-Timer0-FPSAWTAnimator#00-Timer1> at processing.opengl.PSurfaceJOGL$2.run(PSurfaceJOGL.java:459) at java.lang.Thread.run(Thread.java:745)

Ask me if you need any more informations :)

«1

Answers

  • edited December 2016

    Hi @laimperiestro

    That's a post I actually posted myself (didn't even remember)

    But the answer I had were about my second question about Beads itself, here I'm just asking about an error I get only when I use this librairy :)

    (I have done some test and I think the program takes time to start because of the AudioContext)

  • edited December 2016

    Ok, we really need some sample code which can replicate your problem in order to answer your question.
    Don't bother with posting your entire code, just a small sample which also has your problem in it. And remember to format your code.

  • edited December 2016

    @Lord_of_the_Galaxy

    https://paste2.org/DZ5vjkUa

    Here is my whole code about music in my program, the audiocontext() line 9 make the code lags few seconds when I compile it.

  • Are you sure it's the audio context taking too long and not the sample loading? What happens if you don't load the samples? What about if you use a wav file?

    Never have an empty catch - always print the exception so you can read it.

  • Are you sure if that is what is causing the problem? In any case, I don't see why you're worried. That code is just the startup code and shouldn't slow down the sketch itself.
    As to the error, surround the problem code with a try block and use printStackTrace() method of Exception to check what exactly is the problem.

  • I had something a printStackTrace() in my catch but it never printed me any error, the error comes from samples loading too ofc, the whole library cause trouble in general.

    https://paste2.org/gLazemBF

    I never saw my print (from catch), that's why I'm asking because I lost with this.

  • I also see that the bigger my samples are the longer my program takes time to load.

  • Then it obviously means that the loading takes time.
    And I don't see why you can't wait for the program to load - how long could it possibly take? A minute at most?

  • I don't mind waiting, the problem is that after 5second processing stop itself and give me the error I first paste ^^ (I perfectly know that big programs take long time to load)

  • Which line causes the erro?

  • I don't know, maybe no one. But the code inside my try() is the thing that make the program loading and the loading causes the error. So directly I think no line gives an error.

  • Something isn't right - how can something inside a try block even cause the program to crash?

  • edited December 2016

    I actually don't know, I searched and never found a problem like mine.

  • Because the "crash", actually a timeout, is from a JOGL monitoring thread, not the main animation one. See eg. https://github.com/processing/processing/issues/4468

  • Yes that's what I thought (without knowing what actually happen)

    In this post, the solution was about changing the order but I already tried that :/

  • If I understood the discussion in the Github issue correctly, it's because JOGL is initialising the canvas and is waiting for Processing to start drawing on it, but because Processing is busy it can't return an image in less than five seconds. We'll have to somehow make sure this doesn't happen.

    Try:

    • create a void settings() method where you call size(). I have no clue if this will work but my logic is Processing will create a new frame after settings() and before setup() and while setup() is running, it will just return the default grey image to JOGL to keep it happy.

    • Move your resource loading to a separate thread so setup() can finish sooner. Write some logic in draw() that checks if the objects that are being loaded are null and when they are loaded (no longer null), start the actual program.

  • edited December 2016

    I'm going to try the first one but I actually didn't get your second idea ^^

    Edit : First one changes nothing

  • edited December 2016 Answer ✓

    It's simple actually as Processing simplifies the process with thread()-

    boolean loaded = false;//has it been loaded?
    void setup(){
      size(?);
      //other non-loading code
      thread("loadFiles");//AFAIK there is no inbuilt "loadFiles" method in PApplet
    }
    
    synchronized void draw(){
      if(!loaded){
        background(0);//my preferences, just do what you want
        textSize(50);
        fill(255);
        text("Loading...", width/2 - textWidth("Loading...")/2, height/2 - 25);
        //You can do more fancy stuff, like showing how much has loaded, but this is minimalist 
      }else{
        //Normal drawing code
      } 
    }  
    
    void loadFiles(){
      //all file loading code here
      synchronized(this){
        loaded = true;
      }
    }  
    
  • On your line 22 I have an error that says boolean is not a valid type's argument for the synchronized statement for the bool loaded

  • edited December 2016

    If sketchPath works in settings(), why not load files in there?

    In the above code, changing synchronized(loaded) to synchronized(this) should work.

  • What does synchronized do with respect to draw()?

    Kf

  • Makes sure that loaded doesn't change halfway through draw, and also makes sure that draw actually sees that loaded has changed.

  • edited December 2016

    In the above code, changing synchronized(loaded) to synchronized(this) should work.

    or write Boolean with a capital letter in line 1.

    or not

  • What is the difference between capital and normal letter ? :o

  • DO NOT write Boolean. You'll be syncing on different values.

  • DO NOT write Boolean. You'll be syncing on different values.

    Can you explain why this is?

  • Synchronized uses a lock that forms part of a Java Object. The synchronized method will lock on PApplet, as will synchronized(this). Using Boolean will lock on the Boolean object assigned to that field. For thread safety the two threads need to lock on the same object.

    Also, Boolean.TRUE and Boolean.FALSE are different objects, so different locks. You'll lock on something different depending on what the field is set to. You should never lock on a mutable field for this reason.

  • I had actually meant to do what @colouredmirrorball suggested, but made a typing mistake. However, since @neilcsmith_net says not to do that, I have changed the code to have synchronized(this). I didn't know that, so thanks @neilcsmith_net.

  • @kfrajer I actually don't know much about it myself, except that not doing that occasionally causes an error because loaded is sometimes being changed right after the time draw() is accessing it. Besides, this code is from an older project of mine that has more variables to keep track of how much has been loaded, and this increases the chance of an error.
    @neilcsmith_net the reason for this was that if it is loaded in settings() it will take a long time to load, something which according to the OP and the discussion in this post causes an error.

  • @Lord_of_the_Galaxy note I said try settings not setup. That's called before JOGL starts up. The point was that if the loading can be done before setup() then that error won't be thrown. Multi-threaded code is difficult to get right, as you've seen! ;-)

  • Oh, I didn't know that either.
    Indeed, if one is willing to wait, loading everything in settings() is perhaps the easiest option.

  • @neilcsmith_net

    Makes sure that loaded doesn't change halfway through draw, and also makes sure that draw actually sees that loaded has changed.

    No experience on this but interesting topic. So you are saying that I cannot modified loaded in draw this way while loadFile() is running in its own thread??

    In general, looking at this code posted above, there is no line that will modify loaded within draw(). It shouldn't be a concern in this case. Am I right?

    Kf

  • @kfrajer All I know is this - it once caused an error in one of my programs, and it took me some time to find the error. Since then, I have always been using the synchronized keyword and it never surfaced again.

  • edited December 2016

    And the problem by the way is that loaded may change halfway between draw, and that may cause an error (Who knows why?).
    So here is what I think.
    The lock on loaded is currently belonging to the loadFiles() thread, when draw() suddenly tried to access it. This leads to draw() accessing a variable that currently belongs to another thread, leading to an error. As to why it was designed so, I don't know.

  • edited December 2016

    @kfrajer no, that's not what I mean. Only one thread may have hold of the lock belonging to an object at a time. When the thread running loadFiles reaches the synchronized block it asks for the lock. If the thread running the animation is in the middle of draw() then because that method is now synchronized it is holding the lock that belongs to 'this'. So, the thread running loadFiles will have to wait until that call to draw is finished and the animation thread gives up the lock before it can continue and set the variable. Therefore the value of loaded only changes between one frame and the next.

    In your particular case you might be alright without locking except that the other thing that synchronized does is make sure other threads see that a field has been updated. The JVM can cache values, so it is theoretically possible in a situation like this that the JVM notices that you don't change loaded in the draw thread and never hit a synchronized block so caches the false value for loaded and draw never sees true.

    @Lord_of_the_Galaxy you should really go find a good Java tutorial on threads if you're going to use them. Your misunderstanding of how they function is likely to get you in more trouble. I say Java, not Processing, as the threading examples I've seen on processing.org also have issues.

  • @neilcsmith_net I have tried and failed to find one - they just don't seem to make much sense.
    In any case, I don't use multithreading much, other than an occasional one, and even then it is fairly simple.

  • edited March 2017

    Hi i'm back here because i'm still using th same method to load my files (mostly sound).

    Here is my code :

        SamplePlayer music, sound1, sound2;
        Gain musicGain, soundGain
    
        Boolean loaded;
    
        void loadFiles()
        {
            try {
            ac = new AudioContext();
            music = new SamplePlayer(ac, new Sample(sketchPath("data/...")));
            sound2 = new SamplePlayer(ac, new Sample(sketchPath("data/s...")));
            sound2 = new SamplePlayer(ac, new Sample(sketchPath("data/...")));
          }
          catch(Exception e)
          {
            println("!");
            e.printStackTrace(); 
            exit();
          }
          /**
          sonTir1.setKillOnEnd(false);
          sonTir2.setKillOnEnd(false);
          musiqueMenu.setKillOnEnd(false);
    
          musiqueGain = new Gain(ac, 1, musiqueVolume/1000);  //0.05)
          sonGain = new Gain(ac, 1, sonVolume/1000); //0)
    
          musiqueMenu.setLoopType(SamplePlayer.LoopType.LOOP_FORWARDS);
    
          musiqueGain.addInput(musiqueMenu); 
          sonGain.addInput(sonTir1);
          sonGain.addInput(sonTir2);
    
          ac.out.addInput(musiqueGain); 
          ac.out.addInput(sonGain);*/
    
          ac.start();
    
          musiqueMenu.reTrigger();
    
    
          synchronized (loaded) 
          { 
            loaded = true;
          } }
    
        void setup() 
        {
        size(1000, 600, P3D); 
        frameRate(120);
        thread("loadFiles");
        }
    
    
        synchronized void draw() 
        {
          if (!loaded) 
          {
            //text
          } else 
          {
        //run 
        }
        }
    

    So this is the structure of how I use multi-threading, but you can see that inside my try{} there is only 3 files. In my actual program I want to use about 10 to 15 musics but my program takes forever to load, is there a way to make it faster ?

    Thanks :)

  • Define "forever".

    P.S. I think line 42 should be synchronized(this). Ask @neilcsmith_net for more info.

  • edited March 2017

    When I say forever, I mean 1 minute wich is way to long for a few sound files

  • Strange. Is it the same if don't use multithreading?

  • Yes, definitely synchronized(this) if you want to synchronize with draw() otherwise they're not synchronized at all.

  • It's better with synchronized(this) but still the same about the length :/

    Yes

    By the way (while we're talking), how do I disable fullscreen mode or remove the task bar on a program ?

  • synchronized(this) won't do anything about the speed, it'll just help make sure it doesn't break!

    How big are the files you're trying to load?

  • I have like 30 mp3 files around 10Mo each

  • That's 300MB. Quite a bit.

  • Actually, quite a bit more than that! The data will be uncompressed into two (stereo files?) float[] inside Beads.

    Obviously, with mp3 the filesize itself doesn't tell us duration, but a 3min. mp3 would be uncompressed to use

    44100 (sample rate) * 2 (channels) * 180 (seconds) * 4 (bytes per float) = 63504000 bytes, or just over 60MB.

    That's more like 1.75GB for 30 files! That's a lot of heap memory to allocate and fill, not to mention the time for decompression. I can't remember if Beads has support for streaming audio directly from files, but I would look into that. Are you using all the files at the same time - can you load them as required?

  • That's quite strange.

    BTW I meant file size on disk. Even if you just store the compressed version to RAM, you'll still end up using a fair bit of RAM.

    Use a sensible technique for this. Load up only those sound files you'll be using soon.

  • I've never tried to load them when it's needed because it really appeared awful, I may try this

Sign In or Register to comment.