Csound Csound-dev Csound-tekno Search About

[CSOUND-DEV:5597] RE: FLTK threading rules and Csound4

Date2004-12-28 01:00
From"Michael Gogins"
Subject[CSOUND-DEV:5597] RE: FLTK threading rules and Csound4
The console version of csound 5, and the CsoundVST version, will both run 
the FLTK orchestras.

----- Original Message ----- 
From: "John D. Ramsdell" 
To: "Csound Developers Discussion List" 
Sent: Monday, December 27, 2004 4:17 PM
Subject: [CSOUND-DEV:5596] RE: FLTK threading rules and Csound4


> Victor Lazzarini  writes:
>
>> Widgets.cpp on csound5 uses Fl::lock etc.
>
> This made me optimistic that one need only back port the Csound5
> version of widgets.cpp to Csound4, but after reviewing the file, I
> don't think it's that easy.  This code puts an Fl::lock/Fl::unlock
> pair around two occurrences of Fl::wait.  That's because there are two
> threads that perform an Fl::wait!
>
> Once again, this is bad news for CsoundVST and flCsound.  My reading
> of the FLTK manual says that only the main thread is permitted to call
> Fl::wait or Fl::check.  And there is another potential problem.  FLTK
> accesses in child threads should be surround by Fl::lock/Fl::unlock
> pairs, but the main thread should call the Fl::lock once, and hold the
> lock.  The routines in the Csound5 version of widgets.cpp are
> appropriate for use in child threads, but never as the main thread.
> My question is, what happens when Csound5 is run in console only mode?
> What thread is the main thread?  It cannot be the one that runs
> fltkRun, as it drops its lock after each call to Fl::wait.
>
>> I don't think the FLTK lib check is needed, because csound5
>> will not build properly if FL::lock() is not there.
>
> I don't understand why one cannot design Csound5 so that it can be
> built when FLTK is available only as a single threaded library.
>
> Once widgets.cpp is multi-threading enabled in Csound4, the Csound4
> autoconf script will be changed so it only builds libcsound with FLTK
> routines when the FLTK library supports multi-threading.  It will
> build flCsound whenever FLTK is present.  The single threaded version
> of flCsound works just fine in this case.
>
> John
>
> 

Date2004-12-28 15:12
Fromramsdell@mitre.org (John D. Ramsdell)
Subject[CSOUND-DEV:5598] RE: FLTK threading rules and Csound4
"Michael Gogins"  writes:

> The console version of csound 5, and the CsoundVST version, will
> both run the FLTK orchestras.

I'm not suggesting otherwise.  I was just pointing out that, when
Csound5 libcsound is linked and run as part of CsoundVST, all of the
methods in widgets.cpp must follow the rules for child threads--they
must acquire a lock before they access or modify FLTK, and release the
lock when they are done.  If console csound is to use the same widget
library, it must supply it own FLTK main thread.  I have enclosed
ccsound.cpp, a main routine for console csound that does just that.
Tell me what you think of this idea.  It's checked into the csound
module, but it's not part of any of makefiles yet.

--------------------- csound/ccsound.cpp -------------------------
/* Console Csound using the Csound API. */

#include 
#include 
#include 
#include 
#include "csound.h"

#if defined HAVE_FL__LOCK 
#  if defined HAVE_PTHREAD_H
#    include 
#    define USE_THREADS
#    define thread_exit() return 0

typedef pthread_t thread_t;
typedef void *result_t;

namespace {
  int thread_create(thread_t *t, void *(*f)(void *), void *p)
  {
    return pthread_create(t, 0, f, p);
  }
};
#  elif defined WIN32
#    include 
#    include 
#    define USE_THREADS
#    define thread_exit() return

typedef unsigned long thread_t;
typedef void __cdecl result_t;

namespace {
  int thread_create(thread_t *t, void (__cdecl *f)(void *), void *p) 
  {
    *t = _beginthread(f, 0, p);
    if (*t != (thread_t)-1)
      return 0;
    else
      return errno;
  }
};
#  endif
#endif

#if defined USE_THREADS
namespace {
  result_t run(void *csound)
  {
    Fl::lock();
    Fl::run();
    thread_exit();
  }
};
#endif

int main(int argc, char **argv)
{
  void *csound = csoundCreate(0);
#if defined USE_THREADS
  thread_t t;
  int i = create_thread(&t, run, csound);
  if (i) {
    perror(i);
    return 1;
  }
#endif
  int rc = csoundPerform(csound, argc, argv);
  csoundCleanup(csound);
  csoundReset(csound);
  csoundDestroy(csound);
  return rc;
}

Date2004-12-28 15:27
Fromramsdell@mitre.org (John D. Ramsdell)
Subject[CSOUND-DEV:5599] RE: FLTK threading rules and Csound4
ramsdell@mitre.org (John D. Ramsdell) writes:

>   result_t run(void *csound)
>   {
>     Fl::lock();
>     Fl::run();
>     thread_exit();
>   }
> };

Oh wait, that's not going to work.  Fl::run will exit immediately
because there are no windows.  I guess, somehow, fltkRun has to figure
out if there is an existing Fl::run that is active, and only if not,
perform the Fl::lock Fl::run sequence.

John

Date2004-12-28 17:27
Fromramsdell@mitre.org (John D. Ramsdell)
Subject[CSOUND-DEV:5600] RE: FLTK threading rules and Csound4
"Michael Gogins"  writes:

> The console version of csound 5, and the CsoundVST version, will
> both run the FLTK orchestras.

So far, the only viable, thread-safe method I can think of to support
both CsoundVST and console Csound involves changing the semantics of
the Csound API.  I suggest that FLTK GUI clients of the API be
required to call void csoundSetIsGraphable(void *, int) with a
negative number as its second argument before anything is performed.  

When informed of being a used by an FLTK GUI, the widgets would be
used in slave mode.  In slave mode, all FLTK access would be
encapsulated by an Fl::lock/Fl::unlock pair, and the FLrun opcode
would just show its panels.  It would not create a thread.

In master mode, each FLTK access performed before FLrun would not be
encapsulated by an Fl::lock/Fl::unlock pair, and the FLrun opcode
would run a thread that immediately calls Fl::lock, and later on,
Fl::run.  This thread would be console Csound's main thread.

John

> ----- Original Message ----- 
> From: "John D. Ramsdell" 
> To: "Csound Developers Discussion List" 
> Sent: Monday, December 27, 2004 4:17 PM
> Subject: [CSOUND-DEV:5596] RE: FLTK threading rules and Csound4
> 
> 
> > Victor Lazzarini  writes:
> >
> >> Widgets.cpp on csound5 uses Fl::lock etc.
> >
> > This made me optimistic that one need only back port the Csound5
> > version of widgets.cpp to Csound4, but after reviewing the file, I
> > don't think it's that easy.  This code puts an Fl::lock/Fl::unlock
> > pair around two occurrences of Fl::wait.  That's because there are two
> > threads that perform an Fl::wait!
> >
> > Once again, this is bad news for CsoundVST and flCsound.  My reading
> > of the FLTK manual says that only the main thread is permitted to call
> > Fl::wait or Fl::check.  And there is another potential problem.  FLTK
> > accesses in child threads should be surround by Fl::lock/Fl::unlock
> > pairs, but the main thread should call the Fl::lock once, and hold the
> > lock.  The routines in the Csound5 version of widgets.cpp are
> > appropriate for use in child threads, but never as the main thread.
> > My question is, what happens when Csound5 is run in console only mode?
> > What thread is the main thread?  It cannot be the one that runs
> > fltkRun, as it drops its lock after each call to Fl::wait.
> >
> >> I don't think the FLTK lib check is needed, because csound5
> >> will not build properly if FL::lock() is not there.
> >
> > I don't understand why one cannot design Csound5 so that it can be
> > built when FLTK is available only as a single threaded library.
> >
> > Once widgets.cpp is multi-threading enabled in Csound4, the Csound4
> > autoconf script will be changed so it only builds libcsound with FLTK
> > routines when the FLTK library supports multi-threading.  It will
> > build flCsound whenever FLTK is present.  The single threaded version
> > of flCsound works just fine in this case.
> >
> > John
> >
> >