+CV * simpleserver_sv2cv(SV *handler) {
+ STRLEN len;
+ char *buf;
+
+ if (SvPOK(handler)) {
+ CV *ret;
+ buf = SvPV( handler, len);
+ if ( !( ret = perl_get_cv(buf, FALSE ) ) ) {
+ fprintf( stderr, "simpleserver_sv2cv: No such handler '%s'\n\n", buf );
+ exit(1);
+ }
+
+ return ret;
+ } else {
+ return (CV *) handler;
+ }
+}
+
+/* debugging routine to check for destruction of Perl interpreters */
+#ifdef USE_ITHREADS
+void tst_clones(void)
+{
+ int i;
+ PerlInterpreter *parent = PERL_GET_CONTEXT;
+ for (i = 0; i<5000; i++)
+ {
+ PerlInterpreter *perl_interp;
+
+ PERL_SET_CONTEXT(parent);
+ PL_perl_destruct_level = 2;
+ perl_interp = perl_clone(parent, CLONEf_CLONE_HOST);
+ PL_perl_destruct_level = 2;
+ PERL_SET_CONTEXT(perl_interp);
+ perl_destruct(perl_interp);
+ perl_free(perl_interp);
+ }
+ exit (0);
+}
+#endif
+
+int simpleserver_clone(void) {
+#ifdef USE_ITHREADS
+ nmem_mutex_enter(simpleserver_mutex);
+ if (1)
+ {
+ PerlInterpreter *current = PERL_GET_CONTEXT;
+
+ /* if current is unset, then we're in a new thread with
+ * no Perl interpreter for it. So we must create one .
+ * This will only happen when threaded is used..
+ */
+ if (!current) {
+ PerlInterpreter *perl_interp;
+ PERL_SET_CONTEXT( root_perl_context );
+ perl_interp = perl_clone(root_perl_context, CLONEf_CLONE_HOST);
+ PERL_SET_CONTEXT( perl_interp );
+ }
+ }
+ nmem_mutex_leave(simpleserver_mutex);
+#endif
+ return 0;
+}
+
+
+void simpleserver_free(void) {
+ nmem_mutex_enter(simpleserver_mutex);
+ if (1)
+ {
+ PerlInterpreter *current_interp = PERL_GET_CONTEXT;
+
+ /* If current Perl Interp is different from root interp, then
+ * we're in threaded mode and we must destroy..
+ */
+ if (current_interp != root_perl_context) {
+ PL_perl_destruct_level = 2;
+ PERL_SET_CONTEXT(current_interp);
+ perl_destruct(current_interp);
+ perl_free(current_interp);
+ }
+ }
+ nmem_mutex_leave(simpleserver_mutex);
+}
+
+