mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			189 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (c) 2010 Jens Nyberg
 | 
						|
 | 
						|
Permission is hereby granted, free of charge, to any person
 | 
						|
obtaining a copy of this software and associated documentation
 | 
						|
files (the "Software"), to deal in the Software without
 | 
						|
restriction, including without limitation the rights to use,
 | 
						|
copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
						|
copies of the Software, and to permit persons to whom the
 | 
						|
Software is furnished to do so, subject to the following
 | 
						|
conditions:
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be
 | 
						|
included in all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
						|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 | 
						|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
						|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 | 
						|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 | 
						|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
						|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | 
						|
OTHER DEALINGS IN THE SOFTWARE. */
 | 
						|
 | 
						|
#include <fudge.h>
 | 
						|
#include <kernel.h>
 | 
						|
#include <modules/system/system.h>
 | 
						|
#include "pipe.h"
 | 
						|
 | 
						|
static struct system_node root;
 | 
						|
static struct system_node clone;
 | 
						|
 | 
						|
static unsigned int read(struct pipe_end *endself, struct pipe_end *endtarget, struct service_state *state, unsigned int count, void *buffer)
 | 
						|
{
 | 
						|
 | 
						|
    count = buffer_rcfifo(&endself->buffer, count, buffer);
 | 
						|
 | 
						|
    if (!count && endtarget->node.refcount)
 | 
						|
    {
 | 
						|
 | 
						|
        list_add(&endself->readlinks, &state->link);
 | 
						|
        task_setstatus(state->link.data, TASK_STATUS_BLOCKED);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    system_wakeup(&endtarget->writelinks);
 | 
						|
 | 
						|
    return count;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static unsigned int write(struct pipe_end *endself, struct pipe_end *endtarget, struct service_state *state, unsigned int count, void *buffer)
 | 
						|
{
 | 
						|
 | 
						|
    count = buffer_wcfifo(&endtarget->buffer, count, buffer);
 | 
						|
 | 
						|
    if (!count)
 | 
						|
    {
 | 
						|
 | 
						|
        list_add(&endself->writelinks, &state->link);
 | 
						|
        task_setstatus(state->link.data, TASK_STATUS_BLOCKED);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    system_wakeup(&endtarget->readlinks);
 | 
						|
 | 
						|
    return count;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static unsigned int end0_read(struct system_node *self, struct service_state *state, unsigned int count, void *buffer)
 | 
						|
{
 | 
						|
 | 
						|
    struct pipe *pipe = (struct pipe *)self->parent;
 | 
						|
 | 
						|
    return read(&pipe->end0, &pipe->end1, state, count, buffer);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static unsigned int end0_write(struct system_node *self, struct service_state *state, unsigned int count, void *buffer)
 | 
						|
{
 | 
						|
 | 
						|
    struct pipe *pipe = (struct pipe *)self->parent;
 | 
						|
 | 
						|
    return write(&pipe->end0, &pipe->end1, state, count, buffer);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static unsigned int end1_read(struct system_node *self, struct service_state *state, unsigned int count, void *buffer)
 | 
						|
{
 | 
						|
 | 
						|
    struct pipe *pipe = (struct pipe *)self->parent;
 | 
						|
 | 
						|
    return read(&pipe->end1, &pipe->end0, state, count, buffer);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static unsigned int end1_write(struct system_node *self, struct service_state *state, unsigned int count, void *buffer)
 | 
						|
{
 | 
						|
 | 
						|
    struct pipe *pipe = (struct pipe *)self->parent;
 | 
						|
 | 
						|
    return write(&pipe->end1, &pipe->end0, state, count, buffer);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static unsigned int clone_child(struct system_node *self, unsigned int count, char *path)
 | 
						|
{
 | 
						|
 | 
						|
    struct list_item *current;
 | 
						|
 | 
						|
    for (current = root.children.head; current; current = current->next)
 | 
						|
    {
 | 
						|
 | 
						|
        struct system_node *node = current->data;
 | 
						|
        struct pipe *pipe = current->data;
 | 
						|
 | 
						|
        if (node == self)
 | 
						|
            continue;
 | 
						|
 | 
						|
        if (pipe->end0.node.refcount || pipe->end1.node.refcount)
 | 
						|
            continue;
 | 
						|
 | 
						|
        return node->child(node, count, path);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void pipe_init(struct pipe *pipe)
 | 
						|
{
 | 
						|
 | 
						|
    buffer_init(&pipe->end0.buffer, 4096, pipe->end0.data);
 | 
						|
    buffer_init(&pipe->end1.buffer, 4096, pipe->end1.data);
 | 
						|
    system_initnode(&pipe->end0.node, SYSTEM_NODETYPE_NORMAL, "0");
 | 
						|
    system_initnode(&pipe->end1.node, SYSTEM_NODETYPE_NORMAL, "1");
 | 
						|
 | 
						|
    pipe->end0.node.read = end0_read;
 | 
						|
    pipe->end0.node.write = end0_write;
 | 
						|
    pipe->end1.node.read = end1_read;
 | 
						|
    pipe->end1.node.write = end1_write;
 | 
						|
 | 
						|
    system_initnode(&pipe->root, SYSTEM_NODETYPE_GROUP | SYSTEM_NODETYPE_MULTI, "pipe");
 | 
						|
    system_addchild(&pipe->root, &pipe->end0.node);
 | 
						|
    system_addchild(&pipe->root, &pipe->end1.node);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void pipe_register(struct pipe *pipe)
 | 
						|
{
 | 
						|
 | 
						|
    system_addchild(&root, &pipe->root);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void pipe_unregister(struct pipe *pipe)
 | 
						|
{
 | 
						|
 | 
						|
    system_removechild(&root, &pipe->root);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void module_init(void)
 | 
						|
{
 | 
						|
 | 
						|
    system_initnode(&root, SYSTEM_NODETYPE_GROUP, "pipe");
 | 
						|
    system_initnode(&clone, SYSTEM_NODETYPE_GROUP, "clone");
 | 
						|
 | 
						|
    clone.child = clone_child;
 | 
						|
 | 
						|
    system_addchild(&root, &clone);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void module_register(void)
 | 
						|
{
 | 
						|
 | 
						|
    system_registernode(&root);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void module_unregister(void)
 | 
						|
{
 | 
						|
 | 
						|
    system_unregisternode(&root);
 | 
						|
 | 
						|
}
 |