El siguiente me da una Infracción de acceso en Windows de 32 bits, dmd.2.052, sin flags. Cuando el destructor es ejecutado por el recolector de basura, el cuadro de mensaje parece estar dañado en el proceso.Mensaje que pasa desde destructor durante la recolección de basura
import std.stdio;
import core.thread;
import core.memory;
import std.concurrency;
class C
{
string m_str;
Tid m_receiverTid;
this(string s, Tid rt) { this.m_str = s; this.m_receiverTid = rt; }
~this() { writeln("Destructor : ",this.m_str);
m_receiverTid.send(this.m_str);
}
}
void receiver() {
try {
while(true) {
receive((string s){writeln("Received: ",s);});
}
} catch (Throwable th) {
writeln("Caught throwable: ",th.toString());
}
}
void main() {
Tid receiverTid = spawn(&receiver);
receiverTid.send("Basic test");
Thread.sleep(5_000_000);
C c1 = new C("c1 Manually deleted",receiverTid);
delete c1;
Thread.sleep(5_000_000);
{
C c2 = new C("c2 Garbage collected",receiverTid);
}
writeln("Running garbage collector..."); // This line needed to flush out the c2 root pointer.
GC.collect();
Thread.sleep(5_000_000);
writeln("Exiting main thread...");
}
Lo anterior produce:
Received: Basic test
Destructor : c1 Manually deleted
Received: c1 Manually deleted
Running garbage collector...
Destructor : c2 Garbage collected
Received: c2 Garbage collected
Caught throwable: object.Error: Access Violation
Exiting main thread...
¿Hay soluciones para este?
¿Hay alguna manera de que el código del destructor sepa si está siendo invocado por el GC o no?
El mensaje que pasa desde un destructor es intrínsecamente inseguro, p. si los subprocesos no GC están congelados por el GC mientras tienen un bloqueo mutex en un cuadro de mensaje compartido, entonces ¿el GC podría estancarse si se envía a un cuadro de mensaje bloqueado? ¿O el código destructor solo tiene lugar en un ciclo de barrido después de que se hayan descongelado todos los hilos?
¿Es seguro que un destructor haga referencia al almacenamiento local de subprocesos, p. podría el ciclo de barrido GC estar en un hilo diferente?