ID:1948592
 
(See the best response by Kaiochao.)
proc/enter_melee_mode_maptext(turf/effect_loc, character/ref, fade_time = 50)
//if(!ref || !ref.loc) return
var obj/o = new//shadowed_maptext(span("combat_maptext", "Stunned!"))
o.name = "maptext: entered combat"
o.loc = effect_loc
o.maptext = "maptext!"
if(ref) o.SetCenter(ref.Cx(), ref.Cy(), ref.z)
//animate(o, pixel_y = o.pixel_y + tiles(1), alpha = 0, time = fade_time)
//new/event/timed_event(fade_time, "soft_dispose", o)
//memory_leak_test(o)
spawn(fade_time)
o.loc = null
//memory_leak_test(o)
return 1


Alright, so garbage collection is working fine for the most part. However, the object created in the above proc causes the player's garbage collection to delay until the object itself is garbage collected. Why? What's going on here?

Here's how the proc is used:

character
proc/on_entered_combat(combat_session/c)
if(!loc || !c) return
if(!combat_sessions)
combat_sessions = list()
enter_melee_mode_maptext(loc)
//queue_maptext("/proc/enter_melee_mode_maptext", params = list(loc, src))

combat_sessions += c


As you can see, nowhere in on_entered_combat() is there a stop, so I'm not understanding the behavior here. Also, combat_sessions is handled on Logout() via a cleanup proc, so that's not it.

If you're interested in the debug output I'm using:

FKI (/login_mob) deleted.
Memory leak test for the maptext: entered combat (/obj) unsuccessful, revealing 1 reference(s).
(1): loc = the grass (datum)
Memory leak test for the maptext: entered combat (/obj) unsuccessful, revealing 1 reference(s).
(1): loc = the grass (datum)
/player dispose() called (time = 48.25)
combat_session ((fki)-player vs 0x3000000) disposing.
combat_session ((fki)-player vs 0x3000000) disposed.
obj (/obj) deleted.
Memory leak test for the player (/player) successful!
obj (/obj) deleted.
obj (/obj) deleted.
Memory leak test for the maptext: entered combat (/obj) successful!
maptext: entered combat (/obj) deleted.
Memory leak test for the maptext: entered combat (/obj) successful!
maptext: entered combat (/obj) deleted.
/player del() called (time = 90.25)
player (/player) deleted.


Notice the time between the player's call to dispose() and its actual deletion is in line with the fade_time delay in the maptext proc.

Any ideas? Thanks.
Have you tried setting the fade time to 0 (or some other static number?) to see if there is any correlation like you mentioned?
The character has a reference to it (ref) in the scope of that spawn() block.

So, you should set it to null, inside the spawn() block, if that's what you want.
@AERProductions: Indeed, that's how I narrowed the issue down initially.

@Kaiochao: I considered that and that's not the problem, as you can see I don't send a reference to the character; ref is null and the problem persists.
In response to FKI
Maybe it is because it is holding that null reference and it is somehow causing some ambiguous problem?

Is there any possible way to program around using that ref?
In response to FKI
Best response
Is it possible that the proc is holding the player as "usr"? It probably is.
@AERProductions: Well a null reference is just that, it wouldn't hold up garbage collection. I tried it though, and as expected, that wasn't it.

@Kaiochao: That was the problem. As soon as I added usr = null, everything worked as expected. The usr variable never crossed my mind.

I spent way too much time on this single issue and I appreciate the help here. I am even less of a fan of the usr variable and its workings after this incident.

Now to go through the rest of the source and apply the same changes.
Good catch, Kaiochao. The usr var is one that a lot of people forget about, as it's silently passed to each called proc.