Unfortunately, I see another, more subtle problem:

Let's assume an external uses helper threads that call Pd API functions. With PDINSTANCE, it must explicitly call /pd_setinstance()/ on each thread to set the appropriate Pd instance, otherwise it would crash (because /pd_this /would be///NULL/).

Usually, helper threads do not call Pd API functions, but I can think of at least one major exception: logging!

In my own code, I sometimes do:

sys_lock();
pd_error(x, "some critical error I absolutely want the user to see");
sys_unlock();

If this external is compiled /without /PDINSTANCE, but Pd is built /with /PDINSTANCE, the external will load properly, but crash on runtime.

There are other cases where an external might want to behave differently depending on whether PDINSTANCE is defined or not. For example: https://git.iem.at/pd/vstplugin/-/blob/master/pd/src/vstplugin~.cpp

Of course, such externals would just need to be recompiled, but it is something to be aware of.

---

Conclusion: "secretly" enabling PDINSTANCE for regular Pd builds can break existing externals in unexpected ways.

Christof

On 04.04.2022 15:00, Christof Ressi wrote:

I was thinking to a way for the transition: we could:
- change the t_pdinstance pd_s_* fields to pointers (and adapt the s_* replacement  macros accordingly),
- export "hidden" globals s_*
- initialize pd_maininstance pd_s_* fields to the global versions.
Yes, this would work. Of course, it would be an ABI break for multi-instance libpd, but I think it would be justified. I guess libpd users rarely rely on pre-build externals, and even if they do, I think it's ok to ask them to recompile.

We should probably also put the global s_* symbols in a deprecation macro that tells external authors to use gensym() instead.

Christof

On 04.04.2022 13:55, Antoine Rousseau wrote:
I very much agree that in the future Pd (and externals) could be always compiled with PDINSTANCE.

I was thinking to a way for the transition: we could:
- change the t_pdinstance pd_s_* fields to pointers (and adapt the s_* replacement  macros accordingly),
- export "hidden" globals s_*
- initialize pd_maininstance pd_s_* fields to the global versions.

CURRENT:
/* m_pd.h */
struct _pdinstance
{
    t_symbol pd_s_float;
}
#define s_float (pd_this->pd_s_float)

/* m_class.c */
t_pdinstance *pdinstance_init(t_pdinstance *x)
{
    dogensym("float",     &x->pd_s_float,    x);
}

PROPOSAL:
/* m_pd.h */
struct _pdinstance
{
    t_symbol  *pd_s_float;
}
#define s_float (*(pd_this->pd_s_float))

/* m_class.c */
#undef s_float
t_symbol s_float;
t_pdinstance *pdinstance_init(t_pdinstance *x)
{
    if(x != &pd_maininstance) x->pd_s_float = gensym("float");
    else {
dogensym("float",     &s_float,    x);
x->pd_s_float = &s_float;
}

What do you think?

I've tried this (in libpd context) almost successfully, but I've encountered a problem: the s_float as seen from an app linked to libpd seems to be uninitialized.
I've tried something simpler:
/* m_class.c */
float myfloat = 10.0;
t_pdinstance *pdinstance_init(t_pdinstance *x)
{
myfloat = 20.0;
printf("pdinstance_init::myfloat: %f\n", myfloat);
}

/* pdtest.c */
extern float myfloat;
int main()
{
    libpd_init();
    printf("myfloat: %f\n", myfloat);
}

cc -I../../../libpd_wrapper -I../../../pure-data/src -O3   -c -o pdtest.o pdtest.c
gcc -o pdtest pdtest.o ../../../libs/libpd.so

$ pdtest
pdinstance_init::myfloat: 20.00000
myfloat: 10.00000

Do you know why pdtest doesn't see the updated value?

Le mer. 30 mars 2022 à 23:51, Christof Ressi <i...@christofressi.com> a écrit :

    AFAICT, the main issue is that multi-instance Pd misses symbols for
    certain global variables, most notably  s_float, s_symbol,
    s_bang, etc.

    The problem is that these are really exported global structs. If
    they
    were *pointers*, we could simply make them point to the
    corresponding
    field in the main Pd instance. But in this case I don't really see a
    solution...

    On 30.03.2022 18:07, IOhannes m zmoelnig wrote:
    >
    > On 3/30/22 17:45, Dan Wilcox wrote:
    >> I lean much more on the side that PDINSTANCE is a low-level, per
    >> project compile option and not general-purpose. If you are using
    >> libpd, then your environment is a bit more custom anyway.
    >
    > i wonder what the penalty would be to turn on PDINSTANCE on Pd?
    >
    >
    > obviously a problem with externals, but maybe we can come up
    with some
    > clever hack (under the assumption, that Pd (the app) only runs a
    > single instance, even if compiled with multi-instance support)
    to use
    > legacy externals - if that is even possible.
    >
    > apart from that?
    >
    > fgadrms
    > IOhannes
    >
    > _______________________________________________
    > Pd-dev mailing list
    > Pd-dev@lists.iem.at
    > https://lists.puredata.info/listinfo/pd-dev



    _______________________________________________
    Pd-dev mailing list
    Pd-dev@lists.iem.at
    https://lists.puredata.info/listinfo/pd-dev


_______________________________________________
Pd-dev mailing list
Pd-dev@lists.iem.at
https://lists.puredata.info/listinfo/pd-dev

_______________________________________________
Pd-dev mailing list
Pd-dev@lists.iem.at
https://lists.puredata.info/listinfo/pd-dev
_______________________________________________
Pd-dev mailing list
Pd-dev@lists.iem.at
https://lists.puredata.info/listinfo/pd-dev

Reply via email to