Yes, let’s consider scenarios for all three possible memory models:

1. Coroutines share the same global and static variables.
2. Coroutines have separate global and static variables, but the
programmer can explicitly pass the same object.
3. Coroutines have separate variables, and the programmer cannot pass
regular objects as shared at all.

Let’s say SDK Susie publishes her library, which depends on LoggerInterface.
Let LoggerInterface internally just use plain fwrite calls and a
shared message array. But Susie’s SDK doesn’t know that.

```php
function flush(): void {
     file_put_contents(implode("\n", $this->logs), FILE_APPEND);
     $this->logs = []; // clean after save error
}
```

Such code, when called from two different coroutines, may write the
same data to the log file twice.

Then, if SDK Susie’s code creates a coroutine and uses LoggerInterface
inside it…

1. …an error will occur.
2. …an error will occur.
3. PHP will not allow the same LoggerInterface object to be used in
different coroutines without changes to the code.

> - Legacy Les is using a LoggerInterface implementation written years
> ago. How does he know whether it is acceptable for use with Susie's library?

For the third memory model, the entire burden of guarantees falls on
SDK Susie, who must think through exactly how to use LoggerInterface.
If SDK Susie has no ability to modify the LoggerInterface, then she is
required to use it outside of coroutines.

For the first and second memory models, the responsibility for correct
behavior lies with SDK Susie, but the difference from the third model
is that SDK Susie can simply forget about it.

---
Ed

Reply via email to