<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Unfortunately, I see another, more subtle problem:</p>
    Let's assume an external uses helper threads that call Pd API
    functions. With PDINSTANCE, it must explicitly call <i>pd_setinstance()</i>
    on each thread to set the appropriate Pd instance, otherwise it
    would crash (because <i>pd_this </i>would be<i> </i><i>NULL</i>).<br>
    <p>Usually, helper threads do not call Pd API functions, but I can
      think of at least one major exception: logging!</p>
    <p>In my own code, I sometimes do:</p>
    <pre>sys_lock();
pd_error(x, "some critical error I absolutely want the user to see");
sys_unlock();</pre>
    <p>If this external is compiled <i>without </i>PDINSTANCE, but Pd
      is built <i>with </i>PDINSTANCE, the external will load
      properly, but crash on runtime.<br>
    </p>
    <p>There are other cases where an external might want to behave
      differently depending on whether PDINSTANCE is defined or not. For
      example:
      <a class="moz-txt-link-freetext" href="https://git.iem.at/pd/vstplugin/-/blob/master/pd/src/vstplugin~.cpp">https://git.iem.at/pd/vstplugin/-/blob/master/pd/src/vstplugin~.cpp</a></p>
    <p>Of course, such externals would just need to be recompiled, but
      it is something to be aware of.</p>
    <p>---<br>
    </p>
    <p>Conclusion: "secretly" enabling PDINSTANCE for regular Pd builds
      can break existing externals in unexpected ways.</p>
    <p>Christof<br>
    </p>
    <div class="moz-cite-prefix">On 04.04.2022 15:00, Christof Ressi
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:0861a01f-14da-166c-df62-d8cebe2ed823@christofressi.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <p> </p>
      <blockquote type="cite">
        <div>I was thinking to a way for the transition: we could:<br>
        </div>
        <div>- change the t_pdinstance pd_s_* fields to pointers (and
          adapt the s_* replacement  macros accordingly), <br>
        </div>
        <div>- export "hidden" globals s_*</div>
        <div>- initialize pd_maininstance pd_s_* fields to the global
          versions.</div>
      </blockquote>
      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.<br>
      <p>We should probably also put the global s_* symbols in a
        deprecation macro that tells external authors to use gensym()
        instead.<br>
      </p>
      <p>Christof<br>
      </p>
      <div class="moz-cite-prefix">On 04.04.2022 13:55, Antoine Rousseau
        wrote:<br>
      </div>
      <blockquote type="cite"
cite="mid:CAOCG5Hw-TAsX9_dYmaQ+z8VhgxwWBARXHdVxhPhW_CvFVVzm=Q@mail.gmail.com">
        <meta http-equiv="content-type" content="text/html;
          charset=UTF-8">
        <div dir="ltr">
          <div>I very much agree that in the future Pd (and externals)
            could be always compiled with PDINSTANCE.</div>
          <div><br>
          </div>
          <div>I was thinking to a way for the transition: we could:<br>
          </div>
          <div>- change the t_pdinstance pd_s_* fields to pointers (and
            adapt the s_* replacement  macros accordingly), <br>
          </div>
          <div>- export "hidden" globals s_*</div>
          <div>- initialize pd_maininstance pd_s_* fields to the global
            versions.</div>
          <div><br>
          </div>
          <div><span style="font-family:monospace">CURRENT:</span></div>
          <div><span style="font-family:monospace">/* m_pd.h */<br>
            </span></div>
          <div><span style="font-family:monospace">struct _pdinstance<br>
              {</span></div>
          <div><span style="font-family:monospace">    t_symbol 
              pd_s_float;</span></div>
          <div><span style="font-family:monospace">}<br>
            </span></div>
          <div><span style="font-family:monospace">#define s_float    
              (pd_this->pd_s_float)</span></div>
          <div><span style="font-family:monospace"><br>
            </span></div>
          <div><span style="font-family:monospace">/* m_class.c */</span></div>
          <div><span style="font-family:monospace">t_pdinstance
              *pdinstance_init(t_pdinstance *x) <br>
            </span></div>
          <div><span style="font-family:monospace">{</span></div>
          <div><span style="font-family:monospace">    dogensym("float",
                  &x->pd_s_float,    x);</span></div>
          <div><span style="font-family:monospace">}</span></div>
          <div><span style="font-family:monospace"><br>
            </span></div>
          <div><span style="font-family:monospace">PROPOSAL:</span></div>
          <div>
            <div><span style="font-family:monospace">/* m_pd.h */<br>
              </span></div>
            <div><span style="font-family:monospace">struct _pdinstance<br>
                {</span></div>
            <div><span style="font-family:monospace">    t_symbol
                 *pd_s_float;</span></div>
            <div><span style="font-family:monospace">}<br>
              </span></div>
            <div><span style="font-family:monospace">#define s_float    
                (*(pd_this->pd_s_float))</span></div>
            <div><span style="font-family:monospace"><br>
              </span></div>
            <div><span style="font-family:monospace">/* m_class.c */</span></div>
            <div><span style="font-family:monospace">#undef s_float<br>
                t_symbol s_float;<br>
              </span></div>
            <div><span style="font-family:monospace">t_pdinstance
                *pdinstance_init(t_pdinstance *x) <br>
              </span></div>
            <div><span style="font-family:monospace">{</span></div>
            <div><span style="font-family:monospace">    if(x !=
                &pd_maininstance) x->pd_s_float =
                gensym("float");</span></div>
            <div><span style="font-family:monospace">    else {</span></div>
            <div><span style="font-family:monospace">       
                dogensym("float",     &s_float,    x);</span></div>
            <div><span style="font-family:monospace">       
                x->pd_s_float = &s_float;<br>
              </span></div>
            <div><span style="font-family:monospace">}</span></div>
            <div><span style="font-family:monospace"><br>
              </span></div>
            <div><span style="font-family:monospace"><font
                  face="arial,sans-serif">What do you think?</font></span></div>
            <div><span style="font-family:monospace"><font
                  face="arial,sans-serif"><br>
                </font></span></div>
            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.</div>
          <div>I've tried something simpler:</div>
          <div><span style="font-family:monospace">/* m_class.c */</span></div>
          <div><span style="font-family:monospace">float myfloat = 10.0;</span></div>
          <div>
            <div><span style="font-family:monospace">t_pdinstance
                *pdinstance_init(t_pdinstance *x)<br>
              </span></div>
            <div><span style="font-family:monospace">{</span></div>
            <div><span style="font-family:monospace">    <span
                  style="font-family:monospace">myfloat = 20.0;</span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace">    <span
                    style="font-family:monospace"><span
                      style="font-family:monospace"><span
                        style="font-family:monospace">printf("<span
                          style="font-family:monospace"><span
                            style="font-family:monospace"><span
                              style="font-family:monospace"><span
                                style="font-family:monospace"><span
                                  style="font-family:monospace"><span
                                    style="font-family:monospace">pdinstance_init::</span></span></span></span></span></span>myfloat:
                        %f\n", myfloat);</span></span></span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace">}</span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><br>
                </span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace">/* pdtest.c */</span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">extern float myfloat;</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">int main()</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">{</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">    libpd_init();</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">    printf("myfloat:
                    %f\n", myfloat);</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">}</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace"><br>
                  </span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">cc
                    -I../../../libpd_wrapper -I../../../pure-data/src
                    -O3   -c -o pdtest.o pdtest.c<br>
                    gcc -o pdtest pdtest.o ../../../libs/libpd.so</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace"><br>
                  </span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">$ pdtest<br>
                  </span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace"><span
                      style="font-family:monospace"><span
                        style="font-family:monospace"><span
                          style="font-family:monospace"><span
                            style="font-family:monospace"><span
                              style="font-family:monospace"><span
                                style="font-family:monospace"><span
                                  style="font-family:monospace"><span
                                    style="font-family:monospace"><span
                                      style="font-family:monospace"><span
                                        style="font-family:monospace"><span
                                          style="font-family:monospace"><span
style="font-family:monospace"><span style="font-family:monospace"><span
style="font-family:monospace">pdinstance_init::</span></span></span></span></span></span></span></span></span></span></span>myfloat:
                          20.00000</span></span></span></span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace">myfloat: 10.00000</span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace"><br>
                  </span></span></span></div>
            <div><span style="font-family:monospace"><span
                  style="font-family:monospace"><span
                    style="font-family:monospace"><font
                      face="arial,sans-serif">Do you know why pdtest
                      doesn't see the updated value?</font><br>
                  </span></span></span></div>
            <span style="font-family:monospace"></span></div>
        </div>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">Le mer. 30 mars 2022
            à 23:51, Christof Ressi <<a
              href="mailto:info@christofressi.com"
              moz-do-not-send="true" class="moz-txt-link-freetext">info@christofressi.com</a>>
            a écrit :<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">AFAICT, the main issue is
            that multi-instance Pd misses symbols for <br>
            certain global variables, most notably  s_float, s_symbol,
            s_bang, etc.<br>
            <br>
            The problem is that these are really exported global
            structs. If they <br>
            were *pointers*, we could simply make them point to the
            corresponding <br>
            field in the main Pd instance. But in this case I don't
            really see a <br>
            solution...<br>
            <br>
            On 30.03.2022 18:07, IOhannes m zmoelnig wrote:<br>
            ><br>
            > On 3/30/22 17:45, Dan Wilcox wrote:<br>
            >> I lean much more on the side that PDINSTANCE is a
            low-level, per <br>
            >> project compile option and not general-purpose. If
            you are using <br>
            >> libpd, then your environment is a bit more custom
            anyway.<br>
            ><br>
            > i wonder what the penalty would be to turn on
            PDINSTANCE on Pd?<br>
            ><br>
            ><br>
            > obviously a problem with externals, but maybe we can
            come up with some <br>
            > clever hack (under the assumption, that Pd (the app)
            only runs a <br>
            > single instance, even if compiled with multi-instance
            support) to use <br>
            > legacy externals - if that is even possible.<br>
            ><br>
            > apart from that?<br>
            ><br>
            > fgadrms<br>
            > IOhannes<br>
            ><br>
            > _______________________________________________<br>
            > Pd-dev mailing list<br>
            > <a href="mailto:Pd-dev@lists.iem.at" target="_blank"
              moz-do-not-send="true" class="moz-txt-link-freetext">Pd-dev@lists.iem.at</a><br>
            > <a href="https://lists.puredata.info/listinfo/pd-dev"
              rel="noreferrer" target="_blank" moz-do-not-send="true"
              class="moz-txt-link-freetext">https://lists.puredata.info/listinfo/pd-dev</a><br>
            <br>
            <br>
            <br>
            _______________________________________________<br>
            Pd-dev mailing list<br>
            <a href="mailto:Pd-dev@lists.iem.at" target="_blank"
              moz-do-not-send="true" class="moz-txt-link-freetext">Pd-dev@lists.iem.at</a><br>
            <a href="https://lists.puredata.info/listinfo/pd-dev"
              rel="noreferrer" target="_blank" moz-do-not-send="true"
              class="moz-txt-link-freetext">https://lists.puredata.info/listinfo/pd-dev</a><br>
          </blockquote>
        </div>
        <br>
        <fieldset class="moz-mime-attachment-header"></fieldset>
        <pre class="moz-quote-pre" wrap="">_______________________________________________
Pd-dev mailing list
<a class="moz-txt-link-abbreviated moz-txt-link-freetext" href="mailto:Pd-dev@lists.iem.at" moz-do-not-send="true">Pd-dev@lists.iem.at</a>
<a class="moz-txt-link-freetext" href="https://lists.puredata.info/listinfo/pd-dev" moz-do-not-send="true">https://lists.puredata.info/listinfo/pd-dev</a>
</pre>
      </blockquote>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
Pd-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Pd-dev@lists.iem.at">Pd-dev@lists.iem.at</a>
<a class="moz-txt-link-freetext" href="https://lists.puredata.info/listinfo/pd-dev">https://lists.puredata.info/listinfo/pd-dev</a>
</pre>
    </blockquote>
  </body>
</html>