Add Channel:peek()
This commit is contained in:
parent
1f16d63ac7
commit
9e07c6adc7
@ -91,6 +91,32 @@ get(channel:|T|) -> T
|
||||
**Returns:**
|
||||
The item removed from the channel.
|
||||
|
||||
**Example:**
|
||||
```markdown
|
||||
>> channel:peek()
|
||||
= "Hello"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `peek`
|
||||
|
||||
**Description:**
|
||||
Returns the next item that will come out of the channel, but without removing
|
||||
it. If the channel is empty, it waits until an item is available.
|
||||
|
||||
**Usage:**
|
||||
```markdown
|
||||
peek(channel:|T|) -> T
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `channel`: The channel from which to remove an item.
|
||||
|
||||
**Returns:**
|
||||
The item removed from the channel.
|
||||
|
||||
**Example:**
|
||||
```markdown
|
||||
>> channel:get()
|
||||
|
@ -68,6 +68,16 @@ public void Channel$get(channel_t *channel, void *out, int64_t item_size, int64_
|
||||
(void)pthread_cond_signal(&channel->cond);
|
||||
}
|
||||
|
||||
public void Channel$peek(channel_t *channel, void *out, int64_t item_size)
|
||||
{
|
||||
(void)pthread_mutex_lock(&channel->mutex);
|
||||
while (channel->items.length == 0)
|
||||
pthread_cond_wait(&channel->cond, &channel->mutex);
|
||||
memcpy(out, channel->items.data, item_size);
|
||||
(void)pthread_mutex_unlock(&channel->mutex);
|
||||
(void)pthread_cond_signal(&channel->cond);
|
||||
}
|
||||
|
||||
public array_t Channel$view(channel_t *channel)
|
||||
{
|
||||
(void)pthread_mutex_lock(&channel->mutex);
|
||||
|
@ -15,6 +15,8 @@ void Channel$give(channel_t *channel, const void *item, int64_t padded_item_size
|
||||
void Channel$give_all(channel_t *channel, array_t to_give, int64_t padded_item_size);
|
||||
void Channel$get(channel_t *channel, void *out, int64_t item_size, int64_t padded_item_size);
|
||||
#define Channel$get_value(channel, t, padded_item_size) ({ t _val; Channel$get(channel, &_val, sizeof(t), padded_item_size); _val; })
|
||||
void Channel$peek(channel_t *channel, void *out, int64_t item_size);
|
||||
#define Channel$peek_value(channel, t) ({ t _val; Channel$peek(channel, &_val, sizeof(t)); _val; })
|
||||
void Channel$clear(channel_t *channel);
|
||||
array_t Channel$view(channel_t *channel);
|
||||
uint32_t Channel$hash(const channel_t **channel, const TypeInfo *type);
|
||||
|
@ -2377,6 +2377,10 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
CORD self = compile_to_pointer_depth(env, call->self, 0, false);
|
||||
(void)compile_arguments(env, ast, NULL, call->args);
|
||||
return CORD_all("Channel$get_value(", self, ", ", compile_type(item_t), ", ", padded_item_size, ")");
|
||||
} else if (streq(call->name, "peek")) {
|
||||
CORD self = compile_to_pointer_depth(env, call->self, 0, false);
|
||||
(void)compile_arguments(env, ast, NULL, call->args);
|
||||
return CORD_all("Channel$peek_value(", self, ", ", compile_type(item_t), ")");
|
||||
} else if (streq(call->name, "clear")) {
|
||||
CORD self = compile_to_pointer_depth(env, call->self, 0, false);
|
||||
(void)compile_arguments(env, ast, NULL, call->args);
|
||||
|
@ -2,6 +2,10 @@ enum Job(Increment(x:Int), Decrement(x:Int))
|
||||
|
||||
func main():
|
||||
jobs := |:Job; max_size=2|
|
||||
>> jobs:give(Increment(5))
|
||||
>> jobs:peek()
|
||||
= Job.Increment(x=5)
|
||||
|
||||
results := |:Int; max_size|
|
||||
>> thread := Thread.new(func():
|
||||
//! In another thread!
|
||||
@ -13,7 +17,6 @@ func main():
|
||||
>> results:give(x-1)
|
||||
)
|
||||
|
||||
>> jobs:give(Increment(5))
|
||||
>> jobs:give(Decrement(100))
|
||||
>> jobs:give(Decrement(100))
|
||||
>> jobs:give(Decrement(100))
|
||||
|
@ -774,6 +774,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
else if (streq(call->name, "get")) return Match(self_value_t, ChannelType)->item_type;
|
||||
else if (streq(call->name, "give")) return Type(VoidType);
|
||||
else if (streq(call->name, "give_all")) return Type(VoidType);
|
||||
else if (streq(call->name, "peek")) return Match(self_value_t, ChannelType)->item_type;
|
||||
else if (streq(call->name, "view")) return Type(ArrayType, .item_type=Match(self_value_t, ChannelType)->item_type);
|
||||
else code_err(ast, "There is no '%s' method for arrays", call->name);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user