# 2021-04-06 fdfdd12345628
## 測驗 `4`
`gcc -lpthread -march=native -latomic lab.c`
callback 時 refcnt 要加一,結束時要減一,因此需要做兩次的 CAS 才可以
```clike
static bool execute_client_callback(bus_client_t *client, void *msg)
{
/* Load the client with which we are attempting to communicate. */
bus_client_t local_client;
__atomic_load(client, &local_client, __ATOMIC_SEQ_CST);
/* Loop until reference count isupdated or client becomes unregistered */
while (local_client.registered) {
/* The expected reference count is the current one + 1 */
bus_client_t new_client = local_client;
++(new_client.refcnt);
/* If CAS succeeds, the client had the expected reference count, and
* we updated it successfully. If CAS fails, the client was updated
* recently. The actual value is copied to local_client.
*/
if(CAS(&(client->refcnt), &(local_client.refcnt), &(new_client.refcnt))){
client->callback(client->ctx, msg);
// Callback done, decrease reference count
__atomic_load(client, &local_client, __ATOMIC_SEQ_CST);
while(local_client.registered){
bus_client_t new_client = local_client;
--(new_client.refcnt);
if(CAS(&(client->refcnt), &(local_client.refcnt), &(new_client.refcnt))){
return true;
}
local_client.refcnt=client->refcnt;
}// inner while
return false;
}// first CAS
local_client.refcnt=client->refcnt;
}// outer while
/* Client was not registered or got unregistered while we attempted to send
* a message
*/
return false;
}
```
:::warning
注意要更新 reference count
:notes: jserv
:::
:::info
1. 已經將 local_client 的值在 CAS failed 後更新。
2. 已經用半形空白重新排版
> 程式碼排版:4 個半形空白
:::