25-Apr-2024 09:02 GMT.
UNDER CONSTRUCTION
[Forum] OS4 design for ObtainSysList/ReleaseSysListANN.lu
Posted on 11-Jul-2004 20:44 GMT by adesigner (Edited on 2004-07-12 02:34:47 GMT by Christophe Decanini)114 comments
View flat
View list
"In the documentation of FindPort() it is said that you should use ObtainSysList(OSL_PORTLIST) and ReleaseSysList() instead of Forbit() and Permit() in OS4."
www.amigaworld.net thread

I believe this is broken design, you can't mix Forbid and semaphore locking. (Edit by Christophe: It has been confirmed that this solution was rejected for OS4) [sort of pseudo code follows]

" static struct MsgPort *Port;

int InitThePort(void)
{
struct MsgPort *newport;
int result = 0;

ObtainSysList(OSL_PORTLIST); /* Forbid(); */
Port = FindPort(MYPORTNAME);
if (Port) {
result = 2;
} else {
newport = AllocMem(sizeof(*newport), MEMF_PUBLIC);
if (newport) {
/* ... init newport ... */
AddPort(newport);
Port = newport;
result = 1;
} else result = 0;
} else result = 0;

ReleaseSysList(OSL_PORTLIST); /* Permit(); */
return result;
}
"

The problem here is that if some other app is using Forbid() locking, it can easily end up AddPort()ng duplicate port with the same name.

This can happen if task A using ObtainSysList reaches just before AddPort, and Task B using Forbid gets scheduled to run. This task will then Forbid, FindPort and get NULL too. Task B (that is run within Forbid) will now continue and create new port and add it to system via AddPort.

Next Task B Permits and lets other tasks run. Now Task A gets to run and continues to AddPort *duplicate* port.

Further problems may arise if application FindPorting for this port is using Forbid. There the port is actually found *before* InitThePort reaches ReleaseSysList. Now if some further initializing of resources is done before this call, messages might get lost in case these initializations fail, and the app assumes no messages can be in the port (the port list is locked after all, so there should't be any, right?).

RemPort has similar issues, but there the problem is that FindPort can find the port even after ObtainSysList is called for RemPort, and thus more messages might appear in the port even after this ObtainSysList.

Note that AddPort/FindPort itself must not break Forbid. There are a lot more ways that things can break down, I just listed some. Also here I only considered public port list, other system lists have even greater problems.

I ask developers to review these findings and if I am wrong, correct me.

Back to Top