Writes the first element of the inbox as a file of a specified type. The 
    type can be 'file', 'fifo' or 'socket' corresponding to typical  files, 
    named pipes (FIFOs). FIFOs and TCP sockets and are volatile i.e. exists only
    as long as the Python process, which created them. FIFOs are local i.e.
    allow to communicate processes only on the same computer.

    This function returns a semi-random name of the file written. By default 
    creates files and fifos in the default temporary directory. To use named 
    pipes the operating system has to support both forks and fifos (not 
    Windows). Sockets should work on all operating systems.

    This function is useful to efficently communicate parallel ``Pipers`` 
    without the overhead of using queues.

    Arguments:

      - type('file', 'fifo', 'socket') [default: 'file'] Type of the created 
        file-like object.
      - prefix(``str``) [default: ``"tmp_papy_%type%"``] Prefix of the file to 
        be created. Should probably identify the ``Worker`` and ``Piper`` type. 
      - suffix(``str``) [default: ``''``] Suffix of the file to be created. 
        Should probably identify the format of the serialization protocol e.g. 
        ``"pickle"`` or deserialized data e.g. ``"nubox"``.
      - dir(``str``) [default: ``tempfile.gettempdir()``] Directory to safe the
        file to. (can be changed only for types ``"file"`` and ``"fifo"``)
      - timeout(``int``) [default: ``320``] Number of seconds to keep the 
        process at the write-end of the ``"socket"`` or ``"pipe"`` alive.

def dump_item(inbox, type='file', prefix=None, suffix=None, dir=None, \
              timeout=320, buffer=None):
    """
    Writes the first element of the inbox as a file of a specified type. The 
    type can be 'file', 'fifo' or 'socket' corresponding to typical  files, 
    named pipes (FIFOs). FIFOs and TCP sockets and are volatile i.e. exists only
    as long as the Python process, which created them. FIFOs are local i.e.
    allow to communicate processes only on the same computer.

    This function returns a semi-random name of the file written. By default 
    creates files and fifos in the default temporary directory. To use named 
    pipes the operating system has to support both forks and fifos (not 
    Windows). Sockets should work on all operating systems.

    This function is useful to efficently communicate parallel ``Pipers`` 
    without the overhead of using queues.

    Arguments:

      - type('file', 'fifo', 'socket') [default: 'file'] Type of the created 
        file-like object.
      - prefix(``str``) [default: ``"tmp_papy_%type%"``] Prefix of the file to 
        be created. Should probably identify the ``Worker`` and ``Piper`` type. 
      - suffix(``str``) [default: ``''``] Suffix of the file to be created. 
        Should probably identify the format of the serialization protocol e.g. 
        ``"pickle"`` or deserialized data e.g. ``"nubox"``.
      - dir(``str``) [default: ``tempfile.gettempdir()``] Directory to safe the
        file to. (can be changed only for types ``"file"`` and ``"fifo"``)
      - timeout(``int``) [default: ``320``] Number of seconds to keep the 
        process at the write-end of the ``"socket"`` or ``"pipe"`` alive.
    
    """
    # get a random filename generator
    names = tempfile._get_candidate_names()
    names.rng.seed() # re-seed rng after the fork
    # try to own the file
    if type in ('file', 'fifo'):
        prefix = prefix or 'tmp_papy_%s' % type
        suffix = suffix or ''
        dir = dir or tempfile.gettempdir()
        while True:
            # create a random file name
            file = prefix + names.next() + suffix#IGNORE:W0622
            if type in ('file', 'fifo'):
                file = os.path.join(dir, file)
                try:
                    if type == 'file':
                        fd = os.open(file, tempfile._bin_openflags, 0600)
                        tempfile._set_cloexec(fd) # ?, but still open
                    elif type == 'fifo':
                        os.mkfifo(file)
                    file = os.path.abspath(file)
                    break
                except OSError, excp:
                    # first try to close the fd
                    try:
                        os.close(fd)
                    except OSError, excp_:
                        if excp_.errno == errno.EBADF:
                            pass
                        # strange error better raise it
                        raise excp_
                    if excp.errno == errno.EEXIST:
                        # file exists try another one
                        continue
                    # all other errors should be raise
                    raise excp

    # the os will create a random socket for us.
    elif type in ('socket',):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # try to bind to a port
        try:
            host = socket.gethostbyaddr(socket.gethostname())[0] # from /etc/hosts
        except socket.gaierror:
            host = urllib.urlopen(PAPY_DEFAULTS['WHATS_MYIP_URL']).read()
        sock.bind(('', 0))           # os-chosen free port on all interfaces 
        port = sock.getsockname()[1] # port of the socket
    else:
        raise ValueError("type: %s not undertood" % type)

    if type == 'file':
        # no forking
        handle = open(file, 'wb')
        os.close(fd) # no need to own a file twice!
        handle.write(inbox[0])
        handle.close() # close handle
        file = (type, file, 0)
    else:
        # forking mode - forks should be waited
        if type == 'fifo':
            pid = os.fork()
            if not pid:
                # we set an alarm for 5min if nothing starts to read 
                # within this time the process gets killed.
                signal.alarm(timeout)
                fd = os.open(file, os.O_EXCL & os.O_CREAT | os.O_WRONLY)
                signal.alarm(0)
                os.write(fd, inbox[0])
                os.close(fd)
                os._exit(0)
            file = (type, file, pid)
        elif type == 'socket':
            sock.listen(1)
            pid = os.fork()
            if not pid:
                # sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                signal.alarm(timeout)
                rsock, (rhost, rport) = sock.accept() # blocks until client connects
                signal.alarm(0)
                rsock.sendall(inbox[0])               # returns if all data was sent
                # child closes all sockets and exits
                rsock.close()
                sock.close()
                os._exit(0)
            # parent closes server socket
            sock.close()
            file = (type, host, port)

        # 0. get pid list and methods for atomic operations
        # 1. add the child pid to the pid list
        # 2. try to wait each pid in the list without blocking:
        #    if success remove pid if not ready pass if OSError child not exists
        #    another thread has waited this child.
        # 0.
        tid = threading._get_ident()
        try:
            pids = PAPY_RUNTIME[tid]
        except KeyError:
            PAPY_RUNTIME[tid] = []
            pids = PAPY_RUNTIME[tid]
        add_pid = pids.append   # list methods are atomic
        del_pid = pids.remove
        # 1.
        add_pid(pid)
        # 2. 
        for pid in pids:
            try:
                killed, status = os.waitpid(pid, os.WNOHANG)
                if killed:
                    del_pid(pid)
            except OSError, excp:
                if excp.errno == os.errno.ECHILD:
                    continue
                raise
    # filename needs still to be unlinked
    return file