mirror of
				https://gitlab.com/sortix/sortix.git
				synced 2023-02-13 20:55:38 -05:00 
			
		
		
		
	Thread secured pipe class.
This commit is contained in:
		
							parent
							
								
									66d7234ab1
								
							
						
					
					
						commit
						dafe1c499d
					
				
					 2 changed files with 88 additions and 13 deletions
				
			
		| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
/******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
						Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	This file is part of Sortix.
 | 
						This file is part of Sortix.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,18 +14,21 @@
 | 
				
			||||||
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
						FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
				
			||||||
	details.
 | 
						details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	You should have received a copy of the GNU General Public License along
 | 
						You should have received a copy of the GNU General Public License along with
 | 
				
			||||||
	with Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
						Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe.cpp
 | 
						pipe.cpp
 | 
				
			||||||
	A device with a writing end and a reading end.
 | 
						A device with a writing end and a reading end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
******************************************************************************/
 | 
					*******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sortix/kernel/platform.h>
 | 
					#include <sortix/kernel/platform.h>
 | 
				
			||||||
 | 
					#include <sortix/kernel/kthread.h>
 | 
				
			||||||
#include <libmaxsi/error.h>
 | 
					#include <libmaxsi/error.h>
 | 
				
			||||||
#include <libmaxsi/memory.h>
 | 
					#include <libmaxsi/memory.h>
 | 
				
			||||||
 | 
					#ifdef GOT_FAKE_KTHREAD
 | 
				
			||||||
#include "event.h"
 | 
					#include "event.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#include "thread.h"
 | 
					#include "thread.h"
 | 
				
			||||||
#include "process.h"
 | 
					#include "process.h"
 | 
				
			||||||
#include "syscall.h"
 | 
					#include "syscall.h"
 | 
				
			||||||
| 
						 | 
					@ -49,10 +52,15 @@ namespace Sortix
 | 
				
			||||||
		size_t buffersize;
 | 
							size_t buffersize;
 | 
				
			||||||
		size_t bufferoffset;
 | 
							size_t bufferoffset;
 | 
				
			||||||
		size_t bufferused;
 | 
							size_t bufferused;
 | 
				
			||||||
 | 
					#ifdef GOT_FAKE_KTHREAD
 | 
				
			||||||
		Event readevent;
 | 
							Event readevent;
 | 
				
			||||||
		Event writeevent;
 | 
							Event writeevent;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		bool anyreading;
 | 
							bool anyreading;
 | 
				
			||||||
		bool anywriting;
 | 
							bool anywriting;
 | 
				
			||||||
 | 
							kthread_mutex_t pipelock;
 | 
				
			||||||
 | 
							kthread_cond_t readcond;
 | 
				
			||||||
 | 
							kthread_cond_t writecond;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		virtual ssize_t Read(byte* dest, size_t count);
 | 
							virtual ssize_t Read(byte* dest, size_t count);
 | 
				
			||||||
| 
						 | 
					@ -74,6 +82,9 @@ namespace Sortix
 | 
				
			||||||
		this->bufferused = 0;
 | 
							this->bufferused = 0;
 | 
				
			||||||
		this->anyreading = true;
 | 
							this->anyreading = true;
 | 
				
			||||||
		this->anywriting = true;
 | 
							this->anywriting = true;
 | 
				
			||||||
 | 
							this->pipelock = KTHREAD_MUTEX_INITIALIZER;
 | 
				
			||||||
 | 
							this->readcond = KTHREAD_COND_INITIALIZER;
 | 
				
			||||||
 | 
							this->writecond = KTHREAD_COND_INITIALIZER;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DevPipeStorage::~DevPipeStorage()
 | 
						DevPipeStorage::~DevPipeStorage()
 | 
				
			||||||
| 
						 | 
					@ -87,6 +98,29 @@ namespace Sortix
 | 
				
			||||||
	ssize_t DevPipeStorage::Read(byte* dest, size_t count)
 | 
						ssize_t DevPipeStorage::Read(byte* dest, size_t count)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( count == 0 ) { return 0; }
 | 
							if ( count == 0 ) { return 0; }
 | 
				
			||||||
 | 
					#ifdef GOT_ACTUAL_KTHREAD
 | 
				
			||||||
 | 
							ScopedLockSignal lock(&pipelock);
 | 
				
			||||||
 | 
							if ( !lock.IsAcquired() ) { Error::Set(EINTR); return -1; }
 | 
				
			||||||
 | 
							while ( anywriting && !bufferused )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( !kthread_cond_wait_signal(&readcond, &pipelock) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Error::Set(EINTR);
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if ( !bufferused && !anywriting ) { return 0; }
 | 
				
			||||||
 | 
							if ( bufferused < count ) { count = bufferused; }
 | 
				
			||||||
 | 
							size_t amount = count;
 | 
				
			||||||
 | 
							size_t linear = buffersize - bufferoffset;
 | 
				
			||||||
 | 
							if ( linear < amount ) { amount = linear; }
 | 
				
			||||||
 | 
							ASSERT(amount);
 | 
				
			||||||
 | 
							Memory::Copy(dest, buffer + bufferoffset, amount);
 | 
				
			||||||
 | 
							bufferoffset = (bufferoffset + amount) % buffersize;
 | 
				
			||||||
 | 
							bufferused -= amount;
 | 
				
			||||||
 | 
							kthread_cond_broadcast(&writecond);
 | 
				
			||||||
 | 
							return amount;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if ( bufferused )
 | 
							if ( bufferused )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( bufferused < count ) { count = bufferused; }
 | 
								if ( bufferused < count ) { count = bufferused; }
 | 
				
			||||||
| 
						 | 
					@ -106,12 +140,41 @@ namespace Sortix
 | 
				
			||||||
		Error::Set(EBLOCKING);
 | 
							Error::Set(EBLOCKING);
 | 
				
			||||||
		readevent.Register();
 | 
							readevent.Register();
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ssize_t DevPipeStorage::Write(const byte* src, size_t count)
 | 
						ssize_t DevPipeStorage::Write(const byte* src, size_t count)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( !anyreading ) { /* TODO: SIGPIPE */ }
 | 
					 | 
				
			||||||
		if ( count == 0 ) { return 0; }
 | 
							if ( count == 0 ) { return 0; }
 | 
				
			||||||
 | 
					#ifdef GOT_ACTUAL_KTHREAD
 | 
				
			||||||
 | 
							ScopedLockSignal lock(&pipelock);
 | 
				
			||||||
 | 
							if ( !lock.IsAcquired() ) { Error::Set(EINTR); return -1; }
 | 
				
			||||||
 | 
							while ( anyreading && bufferused == buffersize )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( !kthread_cond_wait_signal(&writecond, &pipelock) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Error::Set(EINTR);
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if ( !anyreading )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// TODO: Implement better signal support and uncomment.
 | 
				
			||||||
 | 
								//CurrentThread()->DeliverSignal(SIGPIPE);
 | 
				
			||||||
 | 
								Error::Set(EPIPE);
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if ( buffersize - bufferused < count ) { count = buffersize - bufferused; }
 | 
				
			||||||
 | 
							size_t writeoffset = (bufferoffset + bufferused) % buffersize;
 | 
				
			||||||
 | 
							size_t amount = count;
 | 
				
			||||||
 | 
							size_t linear = buffersize - writeoffset;
 | 
				
			||||||
 | 
							if ( linear < amount ) { amount = linear; }
 | 
				
			||||||
 | 
							ASSERT(amount);
 | 
				
			||||||
 | 
							Memory::Copy(buffer + writeoffset, src, amount);
 | 
				
			||||||
 | 
							bufferused += amount;
 | 
				
			||||||
 | 
							kthread_cond_broadcast(&readcond);
 | 
				
			||||||
 | 
							return amount;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
		if ( bufferused < buffersize )
 | 
							if ( bufferused < buffersize )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( buffersize - bufferused < count ) { count = buffersize - bufferused; }
 | 
								if ( buffersize - bufferused < count ) { count = buffersize - bufferused; }
 | 
				
			||||||
| 
						 | 
					@ -129,10 +192,22 @@ namespace Sortix
 | 
				
			||||||
		Error::Set(EBLOCKING);
 | 
							Error::Set(EBLOCKING);
 | 
				
			||||||
		writeevent.Register();
 | 
							writeevent.Register();
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void DevPipeStorage::NotReading() { anyreading = false; }
 | 
						void DevPipeStorage::NotReading()
 | 
				
			||||||
	void DevPipeStorage::NotWriting() { anywriting = false; }
 | 
						{
 | 
				
			||||||
 | 
							ScopedLock lock(&pipelock);
 | 
				
			||||||
 | 
							anyreading = false;
 | 
				
			||||||
 | 
							kthread_cond_broadcast(&readcond);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void DevPipeStorage::NotWriting()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ScopedLock lock(&pipelock);
 | 
				
			||||||
 | 
							anywriting = false;
 | 
				
			||||||
 | 
							kthread_cond_broadcast(&writecond);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class DevPipeReading : public DevStream
 | 
						class DevPipeReading : public DevStream
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
/******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
 | 
						Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	This file is part of Sortix.
 | 
						This file is part of Sortix.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,13 +14,13 @@
 | 
				
			||||||
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
						FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 | 
				
			||||||
	details.
 | 
						details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	You should have received a copy of the GNU General Public License along
 | 
						You should have received a copy of the GNU General Public License along with
 | 
				
			||||||
	with Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
						Sortix. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe.h
 | 
						pipe.h
 | 
				
			||||||
	A device with a writing end and a reading end.
 | 
						A device with a writing end and a reading end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
******************************************************************************/
 | 
					*******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef SORTIX_PIPE_H
 | 
					#ifndef SORTIX_PIPE_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue