mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add channel marshalling.
This commit is contained in:
		| @@ -2,6 +2,7 @@ | |||||||
| All notable changes to this project will be documented in this file. | All notable changes to this project will be documented in this file. | ||||||
|  |  | ||||||
| ## ??? - Unreleased | ## ??? - Unreleased | ||||||
|  | - Channels can now be marshalled. Pending state is not saved, only items in the channel. | ||||||
| - Use the new `.length` function pointer on abstract types for lengths. Adding | - Use the new `.length` function pointer on abstract types for lengths. Adding | ||||||
|   a `length` method will still work as well. |   a `length` method will still work as well. | ||||||
| - Support byte views on abstract types with the `bytes` function pointer. | - Support byte views on abstract types with the `bytes` function pointer. | ||||||
|   | |||||||
| @@ -1175,14 +1175,48 @@ static Janet janet_chanat_next(void *p, Janet key) { | |||||||
|     return janet_nextmethod(ev_chanat_methods, key); |     return janet_nextmethod(ev_chanat_methods, key); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void janet_chanat_marshal(void *p, JanetMarshalContext *ctx) { | ||||||
|  |     JanetChannel *channel = (JanetChannel *)p; | ||||||
|  |     janet_marshal_byte(ctx, channel->closed); | ||||||
|  |     janet_marshal_int(ctx, channel->limit); | ||||||
|  |     int32_t count = janet_q_count(&channel->items); | ||||||
|  |     janet_marshal_int(ctx, count); | ||||||
|  |     JanetQueue *items = &channel->items; | ||||||
|  |     Janet *data = channel->items.data; | ||||||
|  |     if (items->head <= items->tail) { | ||||||
|  |         for (int32_t i = items->head; i < items->tail; i++) | ||||||
|  |             janet_marshal_janet(ctx, data[i]); | ||||||
|  |     } else { | ||||||
|  |         for (int32_t i = items->head; i < items->capacity; i++) | ||||||
|  |             janet_marshal_janet(ctx, data[i]); | ||||||
|  |         for (int32_t i = 0; i < items->tail; i++) | ||||||
|  |             janet_marshal_janet(ctx, data[i]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void *janet_chanat_unmarshal(JanetMarshalContext *ctx) { | ||||||
|  |     JanetChannel *abst = janet_unmarshal_abstract(ctx, sizeof(JanetChannel)); | ||||||
|  |     uint8_t is_closed = janet_unmarshal_byte(ctx); | ||||||
|  |     int32_t limit = janet_unmarshal_int(ctx); | ||||||
|  |     int32_t count = janet_unmarshal_int(ctx); | ||||||
|  |     if (count < 0) janet_panic("invalid negative channel count"); | ||||||
|  |     janet_chan_init(abst, limit, 0); | ||||||
|  |     abst->closed = !!is_closed; | ||||||
|  |     for (int32_t i = 0; i < count; i++) { | ||||||
|  |         Janet item = janet_unmarshal_janet(ctx); | ||||||
|  |         janet_q_push(&abst->items, &item, sizeof(item)); | ||||||
|  |     } | ||||||
|  |     return abst; | ||||||
|  | } | ||||||
|  |  | ||||||
| const JanetAbstractType janet_channel_type = { | const JanetAbstractType janet_channel_type = { | ||||||
|     "core/channel", |     "core/channel", | ||||||
|     janet_chanat_gc, |     janet_chanat_gc, | ||||||
|     janet_chanat_mark, |     janet_chanat_mark, | ||||||
|     janet_chanat_get, |     janet_chanat_get, | ||||||
|     NULL, /* put */ |     NULL, /* put */ | ||||||
|     NULL, /* marshal */ |     janet_chanat_marshal, | ||||||
|     NULL, /* unmarshal */ |     janet_chanat_unmarshal, | ||||||
|     NULL, /* tostring */ |     NULL, /* tostring */ | ||||||
|     NULL, /* compare */ |     NULL, /* compare */ | ||||||
|     NULL, /* hash */ |     NULL, /* hash */ | ||||||
|   | |||||||
| @@ -265,4 +265,15 @@ | |||||||
| (ev/do-thread | (ev/do-thread | ||||||
|   (assert (ev/take ch) "channel packing bug for threaded abstracts on threaded channels.")) |   (assert (ev/take ch) "channel packing bug for threaded abstracts on threaded channels.")) | ||||||
|  |  | ||||||
|  | # marshal channels | ||||||
|  |  | ||||||
|  | (def ch (ev/chan 10)) | ||||||
|  | (ev/give ch "hello") | ||||||
|  | (ev/give ch "world") | ||||||
|  | (def ch2 (-> ch marshal unmarshal)) | ||||||
|  | (def item1 (ev/take ch2)) | ||||||
|  | (def item2 (ev/take ch2)) | ||||||
|  | (assert (= item1 "hello")) | ||||||
|  | (assert (= item2 "world")) | ||||||
|  |  | ||||||
| (end-suite) | (end-suite) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose