blob: e4cabda408fb09878459bf7a3f9fa97f67b1a784 [file] [log] [blame]
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if defined(_PRMWAIT_H)
#else
#define _PRMWAIT_H
#include "prio.h"
#include "prtypes.h"
#include "prclist.h"
PR_BEGIN_EXTERN_C
/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/****************************** WARNING ****************************/
/********************************************************************************/
/**************************** This is work in progress. *************************/
/************************** Do not make any assumptions *************************/
/************************** about the stability of this *************************/
/************************** API or the underlying imple- ************************/
/************************** mentation. ************************/
/********************************************************************************/
/********************************************************************************/
/*
** STRUCTURE: PRWaitGroup
** DESCRIPTION:
** The client may define several wait groups in order to semantically
** tie a collection of file descriptors for a single purpose. This allows
** easier dispatching of threads that returned with active file descriptors
** from the wait function.
*/
typedef struct PRWaitGroup PRWaitGroup;
/*
** ENUMERATION: PRMWStatus
** DESCRIPTION:
** This enumeration is used to indicate the completion status of
** a receive wait object. Generally stated, a positive value indicates
** that the operation is not yet complete. A zero value indicates
** success (similar to PR_SUCCESS) and any negative value is an
** indication of failure. The reason for the failure can be retrieved
** by calling PR_GetError().
**
** PR_MW_PENDING The operation is still pending. None of the other
** fields of the object are currently valid.
** PR_MW_SUCCESS The operation is complete and it was successful.
** PR_MW_FAILURE The operation failed. The reason for the failure
** can be retrieved by calling PR_GetError().
** PR_MW_TIMEOUT The amount of time allowed for by the object's
** 'timeout' field has expired w/o the operation
** otherwise coming to closure.
** PR_MW_INTERRUPT The operation was cancelled, either by the client
** calling PR_CancelWaitFileDesc() or destroying the
** entire wait group (PR_DestroyWaitGroup()).
*/
typedef enum PRMWStatus
{
PR_MW_PENDING = 1,
PR_MW_SUCCESS = 0,
PR_MW_FAILURE = -1,
PR_MW_TIMEOUT = -2,
PR_MW_INTERRUPT = -3
} PRMWStatus;
/*
** STRUCTURE: PRMemoryDescriptor
** DESCRIPTION:
** THis is a descriptor for an interval of memory. It contains a
** pointer to the first byte of that memory and the length (in
** bytes) of the interval.
*/
typedef struct PRMemoryDescriptor
{
void *start; /* pointer to first byte of memory */
PRSize length; /* length (in bytes) of memory interval */
} PRMemoryDescriptor;
/*
** STRUCTURE: PRMWaitClientData
** DESCRIPTION:
** An opague stucture for which a client MAY give provide a concrete
** definition and associate with a receive descriptor. The NSPR runtime
** does not manage this field. It is completely up to the client.
*/
typedef struct PRMWaitClientData PRMWaitClientData;
/*
** STRUCTURE: PRRecvWait
** DESCRIPTION:
** A receive wait object contains the file descriptor that is subject
** to the wait and the amount of time (beginning epoch established
** when the object is presented to the runtime) the the channel should
** block before abandoning the process.
**
** The success of the wait operation will be noted in the object's
** 'outcome' field. The fields are not valid when the NSPR runtime
** is in possession of the object.
**
** The memory descriptor describes an interval of writable memory
** in the caller's address space where data from an initial read
** can be placed. The description may indicate a null interval.
*/
typedef struct PRRecvWait
{
PRCList internal; /* internal runtime linkages */
PRFileDesc *fd; /* file descriptor associated w/ object */
PRMWStatus outcome; /* outcome of the current/last operation */
PRIntervalTime timeout; /* time allowed for entire operation */
PRInt32 bytesRecv; /* number of bytes transferred into buffer */
PRMemoryDescriptor buffer; /* where to store first segment of input data */
PRMWaitClientData *client; /* pointer to arbitrary client defined data */
} PRRecvWait;
/*
** STRUCTURE: PRMWaitEnumerator
** DESCRIPTION:
** An enumeration object is used to store the state of an existing
** enumeration over a wait group. The opaque object must be allocated
** by the client and the reference presented on each call to the
** pseudo-stateless enumerator. The enumeration objects are sharable
** only in serial fashion.
*/
typedef struct PRMWaitEnumerator PRMWaitEnumerator;
/*
** FUNCTION: PR_AddWaitFileDesc
** DESCRIPTION:
** This function will effectively add a file descriptor to the
** list of those waiting for network receive. The new descriptor
** will be semantically tied to the wait group specified.
**
** The ownership for the storage pointed to by 'desc' is temporarily
** passed over the the NSPR runtime. It will be handed back by the
** function PR_WaitRecvReady().
**
** INPUTS
** group A reference to a PRWaitGroup or NULL. Wait groups are
** created by calling PR_CreateWaitGroup() and are used
** to semantically group various file descriptors by the
** client's application.
** desc A reference to a valid PRRecvWait. The object of the
** reference must be preserved and not be modified
** until its ownership is returned to the client.
** RETURN
** PRStatus An indication of success. If equal to PR_FAILUE details
** of the failure are avaiable via PR_GetError().
**
** ERRORS
** PR_INVALID_ARGUMENT_ERROR
** Invalid 'group' identifier or duplicate 'desc' object.
** PR_OUT_OF_MEMORY_ERROR
** Insuffient memory for internal data structures.
** PR_INVALID_STATE_ERROR
** The group is being destroyed.
*/
NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
/*
** FUNCTION: PR_WaitRecvReady
** DESCRIPTION:
** PR_WaitRecvReady will block the calling thread until one of the
** file descriptors that have been added via PR_AddWaitFileDesc is
** available for input I/O.
** INPUT
** group A pointer to a valid PRWaitGroup or NULL (the null
** group. The function will block the caller until a
** channel from the wait group becomes ready for receive
** or there is some sort of error.
** RETURN
** PRReciveWait
** When the caller is resumed it is either returned a
** valid pointer to a previously added receive wait or
** a NULL. If the latter, the function has terminated
** for a reason that can be determined by calling
** PR_GetError().
** If a valid pointer is returned, the reference is to the
** file descriptor contained in the receive wait object.
** The outcome of the wait operation may still fail, and
** if it has, that fact will be noted in the object's
** outcome field. Details can be retrieved from PR_GetError().
**
** ERRORS
** PR_INVALID_ARGUMENT_ERROR
** The 'group' is not known by the runtime.
** PR_PENDING_INTERRUPT_ERROR
The thread was interrupted.
** PR_INVALID_STATE_ERROR
** The group is being destroyed.
*/
NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group);
/*
** FUNCTION: PR_CancelWaitFileDesc
** DESCRIPTION:
** PR_CancelWaitFileDesc is provided as a means for cancelling operations
** on objects previously submitted by use of PR_AddWaitFileDesc(). If
** the runtime knows of the object, it will be marked as having failed
** because it was interrupted (similar to PR_Interrupt()). The first
** available thread waiting on the group will be made to return the
** PRRecvWait object with the outcome noted.
**
** INPUTS
** group The wait group under which the wait receive object was
** added.
** desc A pointer to the wait receive object that is to be
** cancelled.
** RETURN
** PRStatus If the wait receive object was located and associated
** with the specified wait group, the status returned will
** be PR_SUCCESS. There is still a race condition that would
** permit the offected object to complete normally, but it
** is assured that it will complete in the near future.
** If the receive object or wait group are invalid, the
** function will return with a status of PR_FAILURE.
**
** ERRORS
** PR_INVALID_ARGUMENT_ERROR
** The 'group' argument is not recognized as a valid group.
** PR_COLLECTION_EMPTY_ERROR
** There are no more receive wait objects in the group's
** collection.
** PR_INVALID_STATE_ERROR
** The group is being destroyed.
*/
NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
/*
** FUNCTION: PR_CancelWaitGroup
** DESCRIPTION:
** PR_CancelWaitGroup is provided as a means for cancelling operations
** on objects previously submitted by use of PR_AddWaitFileDesc(). Each
** successive call will return a pointer to a PRRecvWait object that
** was previously registered via PR_AddWaitFileDesc(). If no wait
** objects are associated with the wait group, a NULL will be returned.
** This function should be called in a loop until a NULL is returned
** to reclaim all the wait objects prior to calling PR_DestroyWaitGroup().
**
** INPUTS
** group The wait group under which the wait receive object was
** added.
** RETURN
** PRRecvWait* If the wait group is valid and at least one receive wait
** object is present in the group, that object will be
** marked as PR_MW_INTERRUPT'd and removed from the group's
** queues. Otherwise a NULL will be returned and the reason
** for the NULL may be retrieved by calling PR_GetError().
**
** ERRORS
** PR_INVALID_ARGUMENT_ERROR
** PR_GROUP_EMPTY_ERROR
*/
NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group);
/*
** FUNCTION: PR_CreateWaitGroup
** DESCRIPTION:
** A wait group is an opaque object that a client may create in order
** to semantically group various wait requests. Each wait group is
** unique, including the default wait group (NULL). A wait request
** that was added under a wait group will only be serviced by a caller
** that specified the same wait group.
**
** INPUT
** size The size of the hash table to be used to contain the
** receive wait objects. This is just the initial size.
** It will grow as it needs to, but to avoid that hassle
** one can suggest a suitable size initially. It should
** be ~30% larger than the maximum number of receive wait
** objects expected.
** RETURN
** PRWaitGroup If successful, the function will return a pointer to an
** object that was allocated by and owned by the runtime.
** The reference remains valid until it is explicitly destroyed
** by calling PR_DestroyWaitGroup().
**
** ERRORS
** PR_OUT_OF_MEMORY_ERROR
*/
NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size);
/*
** FUNCTION: PR_DestroyWaitGroup
** DESCRIPTION:
** Undo the effects of PR_CreateWaitGroup(). Any receive wait operations
** on the group will be treated as if the each had been the target of a
** PR_CancelWaitFileDesc().
**
** INPUT
** group Reference to a wait group previously allocated using
** PR_CreateWaitGroup().
** RETURN
** PRStatus Will be PR_SUCCESS if the wait group was valid and there
** are no receive wait objects in that group. Otherwise
** will indicate PR_FAILURE.
**
** ERRORS
** PR_INVALID_ARGUMENT_ERROR
** The 'group' argument does not reference a known object.
** PR_INVALID_STATE_ERROR
** The group still contains receive wait objects.
*/
NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);
/*
** FUNCTION: PR_CreateMWaitEnumerator
** DESCRIPTION:
** The PR_CreateMWaitEnumerator() function returns a reference to an
** opaque PRMWaitEnumerator object. The enumerator object is required
** as an argument for each successive call in the stateless enumeration
** of the indicated wait group.
**
** group The wait group that the enumeration is intended to
** process. It may be be the default wait group (NULL).
** RETURN
** PRMWaitEnumerator* group
** A reference to an object that will be used to store
** intermediate state of enumerations.
** ERRORS
** Errors are indicated by the function returning a NULL.
** PR_INVALID_ARGUMENT_ERROR
** The 'group' argument does not reference a known object.
** PR_OUT_OF_MEMORY_ERROR
*/
NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group);
/*
** FUNCTION: PR_DestroyMWaitEnumerator
** DESCRIPTION:
** Destroys the object created by PR_CreateMWaitEnumerator(). The reference
** used as an argument becomes invalid.
**
** INPUT
** PRMWaitEnumerator* enumerator
** The PRMWaitEnumerator object to destroy.
** RETURN
** PRStatus
** PR_SUCCESS if successful, PR_FAILURE otherwise.
** ERRORS
** PR_INVALID_ARGUMENT_ERROR
** The enumerator is invalid.
*/
NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator);
/*
** FUNCTION: PR_EnumerateWaitGroup
** DESCRIPTION:
** PR_EnumerateWaitGroup is a thread safe enumerator over a wait group.
** Each call to the enumerator must present a valid PRMWaitEnumerator
** rererence and a pointer to the "previous" element returned from the
** enumeration process or a NULL.
**
** An enumeration is started by passing a NULL as the "previous" value.
** Subsequent calls to the enumerator must pass in the result of the
** previous call. The enumeration end is signaled by the runtime returning
** a NULL as the result.
**
** Modifications to the content of the wait group are allowed during
** an enumeration. The effect is that the enumeration may have to be
** "reset" and that may result in duplicates being returned from the
** enumeration.
**
** An enumeration may be abandoned at any time. The runtime is not
** keeping any state, so there are no issues in that regard.
*/
NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup(
PRMWaitEnumerator *enumerator, const PRRecvWait *previous);
PR_END_EXTERN_C
#endif /* defined(_PRMWAIT_H) */
/* prmwait.h */