.\" '\" tep .\" to invoke 'tbl', 'eqn', 'pic' in the proper order .\" .\" @(#)queue.3 1.4 00/02/18 SMI; .\" .TH QUEUE 3CC4 "07 August 1997" .\" .SH NAME queue \- list management for the task library .SH SYNOPSIS .LP .nf .ft B #include .sp .5v enum qmodetype { EMODE, WMODE, ZMODE }; .sp .5v class qhead: public object { public: // exported constructor qhead(qmodetype mode=WMODE, int size=10000); .sp .5v // exported virtual functions virtual objtype o_type(); virtual int pending(); virtual void print(int, int=0); .sp .5v // exported misc functions qhead* cut(); object* get(); int putback(object*); int rdcount(); int rdmax(); qmodetype rdmode(); void setmode(qmodetype); void setmax(int); void splice(qtail*); qtail* tail(); }; .sp .5v class qtail: public object { public: // exported constructor qtail(qmodetype mode=WMODE, int size=10000); .sp .5v // exported virtual functions virtual objtype o_type(); virtual int pending(); virtual void print(int, int = 0); .sp .5v // exported misc functions qtail* cut(); qhead* head(); int put(object*); int rdmax(); qmodetype rdmode(); int rdspace(); void setmode(qmodetype); void setmax(int); void splice(qhead*); }; .ft R .fi .\" .SH DESCRIPTION .LP The task system provides a general queue mechanism, where a queue is a first-in first-out list of objects derived from class .B object (see .BR task (3CC4)). No direct access is provided to a queue itself, but access is instead via the member functions of the cooperating classes .BR qhead " and " qtail . Class .B qhead provides access to the head of the queue, primarily for removing the item at the head of the list. Class .B qtail provides access to the tail of the queue, primarily for adding a new item to the end of the queue. .LP To create a queue, first create a .B qhead object, call member function .B qhead::tail() to get access to the associated .BR qtail . Example: .nf .ft B qhead qh; // create a queue qtail *qtp = qh.tail(); // retrieve the qtail .br .ft R .fi Alternatively, the .B qtail object could be created first, using member function .B qtail::head() to get access to the associated .BR qhead . Here is an example using only heap objects: .nf .ft B qtail *qtp = new qtail; // create a queue qhead *qhp = qtp\->head(); // retrieve the qhead .ft R .fi .LP The constructors for these classes have two optional arguments, the queue mode, and the queue maximum size. The queue mode does not affect the normal operation of the queue, but only specifies what happens when an operation is attempted on a .I pending queue. This is further described below. The queue size is the maximum number of items allowed to be on the queue. This is useful for modeling real-world queues which have a maximum size. The size defaults to 10,000 items, but may be reset at any time via the member function .BR setmax() . No space is preallocated for the items on a queue. .LP Once a queue has been created, you may append objects to it with member function .BR qtail::put() , and retrieve the object at the head of the queue with member function .BR qhead::get() . .LP Like all classes derived from class .BR object , queues have a definition of whether they are .IR ready " or " pending , and the definitions are different for the head and tail of the queue. A .B qtail is pending when it is full; that is, when it already has its maximum number of objects. A .B qhead is pending when it is empty. .LP Each of .BR qhead " and " qtail have a mode, set by the mode parameter of the constructor. The mode may be modified at any time by member function .BR setmode() ; the mode need not be the same for the head and tail of the same queue. The mode must be one of these: .TP .B WMODE .IR "wait mode" : Adding to a full .B qtail or removing from an empty .B qhead suspends the requesting task. This mode is set if neither of the other modes is specied. .TP .B ZMODE .IR "zero mode" : Adding to a full .B qtail or removing from an empty .B qhead returns a zero result. .TP .B EMODE .IR "error mode" : Adding to a full .B qtail or removing from an empty .B qhead calls .BR task_error() . .LP Queues may be cut and spliced, allowing the insertion of filters or other tasks into queue processing. This is explained in more detail under the .BR cut() " and " splice() member functions. .\" .SS "Class qhead" .LP .\" .TP .B "qhead qh(m, s);" Constructs a .B qhead object and its associated queue. The queue has mode .B m and maximum size .BR s . The consequences of the mode and size parameters are discussed above. Member function .B tail() returns a pointer to the .B qtail object associated with the queue. .\" .TP .B "objtype ot = qh.o_type();" This virtual function returns the kind of the object. For a .BR qhead , the object kind is QHEAD. .\" .TP .B "int ispending = qh.pending();" This virtual function returns non-zero (true) if the associated queue is empty, and zero (false) otherwise. .\" .TP .B "qh.print(how);" Prints data about the associated queue on .BR stdout " (not " cout ). If the first .BR int " parameter, " how , has the VERBOSE bit set, prints information about all the objects on the queue. The second argument is for internal use and defaults to zero. .\" .TP .B "qhead *qhp = qh.cut();" Creates a new .B qhead attached to the original queue, and returns a pointer to it. Modifies the original .BR qhead " (" qh ) to point to a new empty queue. Use .B qh.tail() to retrieve the .B qtail associated with this new queue. .B qhp will point to the original .BR qhead , and the original .B qtail will still be associated with the original queue. In other words, we have the following situation: .in +.5i .ti -.5i .B qhp\->get() .br Retrieves the first item on the original queue. .ti -.5i .B qhp\->tail()\->put(op) .br Appends an object to the original queue. .ti -.5i .B qh.get() .br Returns the first item on the new queue, once something is put there. .ti -.5i .B qh.tail()\->put(op) .br Appends an object to the new queue. .in -.5i This technique may be used to insert a filter into an existing queue without requiring any change to code using the original head and tail of that queue. The filter will use .B qhp\->get() to retrieve objects that were placed on the queue by putting to the original .BR qtail . The filter will use the equivalent of .B qhp\->tail()\->put(op) to put objects on the new queue which will be retrieved by code referencing the original .BR qhead . Existing code putting and getting from the original queue will result in those object passing through the filter. The queue may be restored by using .BR qhead::splice() . There are .BR cut " and " splice functions associated with .BR qtail , but you must use a pair of functions from the same object, either a .BR qhead " or a " qtail . .\" .TP .B "object *op = qh.get();" If the queue associated with .B qh is not empty, removes the object at the head of the queue and returns a pointer to it. If the queue is empty, the behavior depends on the mode of .BR qh . If the mode is WMODE, the task calling .B get() is suspended until a object is put onto the queue. If the mode is ZMODE, returns a null pointer immediately. If the mode is EMODE, causes a run time error, and .B object::task_error() is called. .\" .TP .B "int ok = qh.putback(op);" If the queue associated with .B qt is not full, puts the object pointed to by .B op at the head of the queue and returns the value .B 1 (true). A queue may be used like a stack by using only the .B qhead and the functions .BR putback() " and " get() . If the queue is full, the behavior depends on the mode of .BR qh . If the mode is WMODE, the task calling .B putback() is suspended until the queue becomes no longer full. If the mode is ZMODE, returns a zero value immediately. If the mode is EMODE, causes a run time error, and .B object::task_error() is called. .\" .TP .B "int i = qh.rdcount();" Returns the number of objects currently in the associated queue. .\" .TP .B "int i = qh.rdmax();" Returns the (current) maximum number of objects allowable in the associated queue. .\" .TP .B "qmodetype qm = qh.rdmode();" Returns the current mode of .BR qh : WMODE, EMODE, or ZMODE. .\" .TP .B "qh.setmode(qm);" Sets the mode of .BR qh " to " qm , which may be one of WMODE, EMODE, or ZMODE. .\" .TP .B "qh.setmax(max);" Sets the maximum number of items allowed on the associated queue to .BR max . It is legal to set the maximum below the current number of objects on the queue. In this case, the queue is considered full until enough objects have been removed to bring the count below the maximum. .\" .TP .B qhp\->splice(qtp); Reverses the previous .B qhead::cut() operation, where .B qhp was the pointer returned by the .BR cut() ", and " qtp points to the .B qtail object associated with .BR qhp . Recall that these head and tail pointers were associated with different queues. The .B splice() operation merges the two queues, and deletes the .BR qhead " and " qtail objects pointed to by .BR qhp " and " qtp . In the merged queue, any objects on the .B qtp queue are placed before any objects on the .B qhp queue. This restored queue again becomes associated with the original .BR qhead " and " qtail objects that were .BR cut() . If merging the queues causes a full queue to become not full, or an empty queue to become not empty, any tasks waiting for that condition will be alerted (made runnable). See .BR task (3CC4). .\" .TP .B "qtail *qtp = qh.tail();" Returns a pointer to the .B qtail object associated with the queue, creating the .B qtail if it does not already exist. .\" .SS "Class qtail" .LP .\" .TP .B "qtail qt(m, s);" Constructs a .B qtail object and its associated queue. The queue has mode .B m and maximum size .BR s . The consequences of the mode and size parameters are discussed above. Member function .B head() returns a pointer to the .B qhead object associated with the queue. .\" .TP .B "objtype ot = qt.o_type();" This virtual function returns the kind of the object. For a .BR qtail , the object kind is QTAIL. .\" .TP .B "int ispending = qt.pending();" This virtual function returns non-zero (true) if the associated queue is full, and zero (false) otherwise. .\" .TP .B "qt.print(how);" Prints data about the associated queue on .BR stdout " (not " cout ). If the first .BR int " parameter, " how , has the VERBOSE bit set, prints information about all the objects on the queue. The second argument is for internal use and defaults to zero. .\" .TP .B "qtail *qtp = qt.cut();" Creates a new .B qtail attached to the original queue, and returns a pointer to it. Modifies the original .BR qtail " (" qt ) to point to a new empty queue. Use .B qt.head() to retrieve the .B qhead associated with this new queue. .B qtp will point to the original .BR qtail , and the original .B qhead will still be associated with the original queue. In other words, we have the following situation: .in +.5i .ti -.5i .B qt.head()\->get() .br Retrieves the first item on the original queue. That is, the original .B qhead still retrieves items from the original queue. .ti -.5i .B qtp\->put(op) .br Appends an object to the original queue. .ti -.5i .B qt.head()\->get() .br Returns the first item on the new queue, once something is put there. .ti -.5i .B qt.put(op) .br Appends an object to the new queue. .in -.5i This technique may be used to insert a filter into an existing queue without requiring any change to code using the original head and tail of that queue. The filter will use the equivalent of .B qtp\->head()\->get() to retrieve objects that were placed on the new queue by putting to the original .BR qtail . The filter will use .B qtp\->put(op) to put objects on the original queue which will be retrieved by code referencing the original .BR qhead . Existing code putting and getting from the original queue will result in those object passing through the filter. The queue may be restored by using .BR qtail::splice() . There are .BR cut " and " splice functions associated with .BR qhead , but you must use a pair of functions from the same object, either a .BR qhead " or a " qtail . .\" .TP .B "qhead *qtp = qt.head();" Returns a pointer to the .B qhead object associated with the queue, creating the .B qhead if it does not already exist. .\" .TP .B "int ok = qt.put(op);" If the queue associated with .B qt is not full, appends the object pointed to by .B op to the queue and returns the value .B 1 (true). If the queue is full, the behavior depends on the mode of .BR qt . If the mode is WMODE, the task calling .B put() is suspended until the queue becomes no longer full. If the mode is ZMODE, returns a zero value immediately. If the mode is EMODE, causes a run time error, and .B object::task_error() is called. .\" .TP .B "int i = qt.rdmax();" Returns the (current) maximum number of objects allowable in the associated queue. .\" .TP .B "qmodetype qm = qt.rdmode();" Returns the current mode of .BR qt : WMODE, EMODE, or ZMODE. .\" .TP .B "int i = qt.rdspace();" Returns the number of objects which may be appended to the associated queue before it becomes full. .\" .TP .B "qt.setmode(qm);" Sets the mode of .BR qt " to " qm , which may be one of WMODE, EMODE, or ZMODE. .\" .TP .B "qt.setmax(max);" Sets the maximum number of items allowed on the associated queue to .BR max . It is legal to set the maximum below the current number of objects on the queue. In this case, the queue is considered full until enough objects have been removed to bring the count below the maximum. .\" .TP .B qtp\->splice(qhp); Reverses the previous .B qtail::cut() operation, where .B qtp was the pointer returned by the .BR cut() ", and " qhp points to the .B qhead object associated with .BR qtp . Recall that these head and tail pointers were associated with different queues. The .B splice() operation merges the two queues, and deletes the .BR qhead " and " qtail objects pointed to by .BR qhp " and " qtp . In the merged queue, any objects on the .B qtp queue are placed before any objects on the .B qhp queue. This restored queue again becomes associated with the original .BR qhead " and " qtail objects that were .BR cut() . If merging the queues causes a full queue to become not full, or an empty queue to become not empty, any tasks waiting for that condition will be alerted (made runnable). See .BR task (3CC4). .\" .SH "DIAGNOSTICS" .LP See .BR task (3CC4). .\" .SH "SEE ALSO" .na .BR TASK.INTRO (3CC4), .BR interrupt (3CC4), .BR task (3CC4), .BR tasksim (3CC4) .LP .I C++ Library Reference Chapter 2, "Coroutine Library." .\" .TZ ????