Dave's Brain

Browse - programming tips - linux selfpipe

Date: 2011nov24
OS: Linux

Q.  How do I make a selfpipe to send a message to myself.

A.  Selfpipes are handy.  They can be use to catch a signal
and send it to a select (But signalfd() does that now).
Or to wake up a select() from another thread.

Here is my selfpipe class:

	--- selfpipe.h ---

	#include <unistd.h>
	#include <fcntl.h>
	#include <syslog.h>
	
	class SelfPipe
	{
		int	selfpipe[2];
	public:
	
		SelfPipe();
		bool poke();
		int getReadFd() const { return selfpipe[0]; }
		int getWriteFd() const { return selfpipe[1]; }
	};
	
	--- selfpipe.cpp ---
	
	#include "selfpipe.h"
	
	SelfPipe::SelfPipe()
	{
		if (pipe(selfpipe) == -1)
		{
			syslog(LOG_ERR, "Could not create a selfpipe -- things are not going to work\n");
			return;
		}
	
		fcntl(selfpipe[0],F_SETFL,fcntl(selfpipe[0],F_GETFL)|O_NONBLOCK);
		fcntl(selfpipe[1],F_SETFL,fcntl(selfpipe[1],F_GETFL)|O_NONBLOCK);
	}
	
	bool SelfPipe::poke()
	{
		return write(getWriteFd(), "X", 1) == 1;
	}
	
	--- end of selfpipe.cpp ---

	--- example main.cpp ---

	#include "selfpipe.h"

	WaitOnTwo(const int fd1, const int selfpipe_fd)
	{
		fd_set			rfds;
	
		FD_ZERO(&rfds);
		FD_SET(fd1, &rfds);
		FD_SET(selfpipe_fd, &rfds);
	
		int nfds = MAX(fd1, selfpipd_fd) + 1;
		return select(nfds, &rfds, NULL, NULL, NULL);
	}

	SelfPipe	selfpipe;

	ThreadMain()
	{
		int		fd1, selfpipe_fd;

		fd1 = OpenSocketOrWhatever();

		for (;;)
		{
			WaitOnTwo(fd1, selfpipe.getReadFd());
		}
	}

	ElseWhere()
	{
		selfpipe.poke();	// Will wake up WaitonTwo()
	}
What this info useful to you? You can donate to say thanks

Add a comment

Sign in to add a comment
Copyright © 2008-2012, dave - Code samples on Dave's Brain is licensed under the Creative Commons Attribution 2.5 License. However other material, including English text has all rights reserved.
Advertisements: