rebol/rebol — pull request #158 by hostilefork (2013-10-01 21:26:36+00:00)
Title: Fix notorious TCP bug (EVM_DEVICE events allowing ports to GC)

Each Rebol value is implemented internally as C structures. For the garbage collector to know which Rebol series (or objects) are being referenced by a value, this C structure must be scanned on a per-type basis. For simple terminal types like an INTEGER! or a CHAR!, there are no embedded types. Clearly BLOCK! holds onto the string series and other values it holds... but there are other instances, which can be subtle (a FUNCTION! holds its spec-block and body-block, for instance... as well as an internal optimized list of arguments generated from the spec.)

The [Mark_Series](https://github.com/rebol/rebol/blob/4d9840f8e661e7067472e828ee6ad8dd3008b247/src/core/m-gc.c#L148) routine is responsible for sniffing the type of a REBSER, and take care of the type-specific behaviors. In two cases it would call type-specific functions in the switch statement: for GOB! and EVENT! objects. The GOB! function was delegated to make as many calls as it wanted to MARK_SERIES or CHECK_SERIES to handle its internal structures, while the EVENT! function was merely to return a single REBSER that it might be referencing.

This pull request does the following:

* Adds handling in the EVENT! GC marking handler to account for the case of being an EVM_DEVICE event type, in which the PORT! object being held onto is not in the VAL_EVENT_SER of the REBEVT structure, rather held indirectly by the REBREQ ->req field of the event. Failure to account for this before was leading to crashes resulting from ports being improperly garbage collected; the "notorious TCP bug".

* The ->req which holds a port can actually be a singly linked list to other REBREQ each of which has its own port. So the code incorporates the question of whether this needs to be walked or not. It does so by defining **NEED_TO_WALK_REBREQ_LIST_FOR_GC**. For the moment, it is set to zero... since @earl [believes it is not necessary](http://chat.stackoverflow.com/transcript/message/12115268#12115268). But remains to document the issue and get it further attention.

+ Reorganizes the code such that the gob! GC marking routine is moved into the t-gob.c file (as the event! GC marking routine had been), and matches the function interface of these two routines so that they may mark an arbitrary number of objects. This required removing the "static" keyword from Mark_Series which previously limited it to being called only from m-gc.c. Potential for the routine being called incorrectly is mitigated by making sure a GC is in progress when it is called.