ACE  6.1.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Types | Private Member Functions | Friends
ACE_Proactor Class Reference

A manager for asynchronous event demultiplexing. More...

#include <Proactor.h>

Collaboration diagram for ACE_Proactor:
Collaboration graph
[legend]

List of all members.

Public Types

typedef int(* PROACTOR_EVENT_HOOK )(ACE_Proactor *)

Public Member Functions

 ACE_Proactor (ACE_Proactor_Impl *implementation=0, bool delete_implementation=false, ACE_Proactor_Timer_Queue *tq=0)
 ~ACE_Proactor (void)
 Destruction.
int close (void)
 Close the associated ACE_Proactor_Impl implementation object.
int proactor_run_event_loop (PROACTOR_EVENT_HOOK=0)
int proactor_run_event_loop (ACE_Time_Value &tv, PROACTOR_EVENT_HOOK=0)
int proactor_end_event_loop (void)
int proactor_event_loop_done (void)
 Report if the ACE_Proactor event loop is finished.
int proactor_reset_event_loop (void)
int register_handle (ACE_HANDLE handle, const void *completion_key)
long schedule_timer (ACE_Handler &handler, const void *act, const ACE_Time_Value &time)
long schedule_repeating_timer (ACE_Handler &handler, const void *act, const ACE_Time_Value &interval)
long schedule_timer (ACE_Handler &handler, const void *act, const ACE_Time_Value &time, const ACE_Time_Value &interval)
int cancel_timer (ACE_Handler &handler, int dont_call_handle_close=1)
int cancel_timer (long timer_id, const void **act=0, int dont_call_handle_close=1)
int handle_events (ACE_Time_Value &wait_time)
int handle_events (void)
int wake_up_dispatch_threads (void)
 Add wakeup dispatch threads (reinit).
int close_dispatch_threads (int wait)
 Close all dispatch threads.
size_t number_of_threads (void) const
 Get number of thread used as a parameter to CreatIoCompletionPort.
void number_of_threads (size_t threads)
 Set number of thread used as a parameter to CreatIoCompletionPort.
ACE_Proactor_Timer_Queuetimer_queue (void) const
 Get timer queue.
void timer_queue (ACE_Proactor_Timer_Queue *timer_queue)
 Set timer queue.
ACE_HANDLE get_handle (void) const
ACE_Proactor_Implimplementation (void) const
 Get the implementation class.
ACE_Asynch_Read_Stream_Implcreate_asynch_read_stream (void)
ACE_Asynch_Write_Stream_Implcreate_asynch_write_stream (void)
ACE_Asynch_Read_File_Implcreate_asynch_read_file (void)
ACE_Asynch_Write_File_Implcreate_asynch_write_file (void)
ACE_Asynch_Accept_Implcreate_asynch_accept (void)
 Create the correct implementation class for doing Asynch_Accept.
ACE_Asynch_Connect_Implcreate_asynch_connect (void)
 Create the correct implementation class for doing Asynch_Connect.
ACE_Asynch_Transmit_File_Implcreate_asynch_transmit_file (void)
ACE_Asynch_Read_Dgram_Implcreate_asynch_read_dgram (void)
ACE_Asynch_Write_Dgram_Implcreate_asynch_write_dgram (void)
ACE_Asynch_Read_Stream_Result_Implcreate_asynch_read_stream_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_read, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Write_Stream_Result_Implcreate_asynch_write_stream_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_write, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Read_File_Result_Implcreate_asynch_read_file_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_read, const void *act, u_long offset, u_long offset_high, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Write_File_Result_Implcreate_asynch_write_file_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_write, const void *act, u_long offset, u_long offset_high, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Read_Dgram_Result_Implcreate_asynch_read_dgram_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, ACE_Message_Block *message_block, size_t bytes_to_read, int flags, int protocol_family, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Write_Dgram_Result_Implcreate_asynch_write_dgram_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE handle, ACE_Message_Block *message_block, size_t bytes_to_write, int flags, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Accept_Result_Implcreate_asynch_accept_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE listen_handle, ACE_HANDLE accept_handle, ACE_Message_Block &message_block, u_long bytes_to_read, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
 Create the correct implementation class for ACE_Asynch_Accept::Result.
ACE_Asynch_Connect_Result_Implcreate_asynch_connect_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE connect_handle, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
 Create the correct implementation class for ACE_Asynch_Connect::Result.
ACE_Asynch_Transmit_File_Result_Implcreate_asynch_transmit_file_result (ACE_Handler::Proxy_Ptr &handler_proxy, ACE_HANDLE socket, ACE_HANDLE file, ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer, u_long bytes_to_write, u_long offset, u_long offset_high, u_long bytes_per_send, u_long flags, const void *act, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)
ACE_Asynch_Result_Implcreate_asynch_timer (ACE_Handler::Proxy_Ptr &handler_proxy, const void *act, const ACE_Time_Value &tv, ACE_HANDLE event=ACE_INVALID_HANDLE, int priority=0, int signal_number=ACE_SIGRTMIN)

Static Public Member Functions

static ACE_Proactorinstance (size_t threads=0)
static ACE_Proactorinstance (ACE_Proactor *proactor, bool delete_proactor=false)
static void close_singleton (void)
 Delete the dynamically allocated Singleton.
static void cleanup (void *instance, void *arg)
static const ACE_TCHARdll_name (void)
 Name of dll in which the singleton instance lives.
static const ACE_TCHARname (void)
 Name of component--ACE_Proactor in this case.
static int run_event_loop (void)
static int run_event_loop (ACE_Time_Value &tv)
static int end_event_loop (void)
static int reset_event_loop (void)
static int check_reconfiguration (ACE_Proactor *)
static int event_loop_done (void)
 Report if the <ACE_Proactor::instance> event loop is finished.

Protected Member Functions

int proactor_post_wakeup_completions (int how_many)
void implementation (ACE_Proactor_Impl *implementation)
 Set the implementation class.

Static Protected Member Functions

static int post_wakeup_completions (int how_many)

Protected Attributes

ACE_Proactor_Implimplementation_
bool delete_implementation_
ACE_Proactor_Timer_Handlertimer_handler_
 Handles timeout events.
ACE_Thread_Manager thr_mgr_
 This will manage the thread in the Timer_Handler.
ACE_Proactor_Timer_Queuetimer_queue_
 Timer Queue.
int delete_timer_queue_
 Flag on whether to delete the timer queue.
sig_atomic_t end_event_loop_
 Terminate the proactor event loop.
sig_atomic_t event_loop_thread_count_
 Number of threads in the event loop.
ACE_SYNCH_MUTEX mutex_
 Mutex to protect work with lists.

Static Protected Attributes

static ACE_Proactorproactor_ = 0
 Pointer to a process-wide ACE_Proactor.
static bool delete_proactor_ = false
 Must delete the <proactor_> if true.

Private Types

typedef
ACE_Timer_Queue_Iterator_T
< ACE_Handler * > 
TIMER_QUEUE_ITERATOR
typedef ACE_Timer_List_T
< ACE_Handler
*, ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX
TIMER_LIST
typedef
ACE_Timer_List_Iterator_T
< ACE_Handler
*, ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX
TIMER_LIST_ITERATOR
typedef ACE_Timer_Heap_T
< ACE_Handler
*, ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX
TIMER_HEAP
typedef
ACE_Timer_Heap_Iterator_T
< ACE_Handler
*, ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX
TIMER_HEAP_ITERATOR
typedef ACE_Timer_Wheel_T
< ACE_Handler
*, ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX
TIMER_WHEEL
typedef
ACE_Timer_Wheel_Iterator_T
< ACE_Handler
*, ACE_Proactor_Handle_Timeout_Upcall,
ACE_SYNCH_RECURSIVE_MUTEX
TIMER_WHEEL_ITERATOR

Private Member Functions

 ACE_Proactor (const ACE_Proactor &)
 Deny access since member-wise won't work...
ACE_Proactoroperator= (const ACE_Proactor &)

Friends

class ACE_Proactor_Timer_Handler

Detailed Description

A manager for asynchronous event demultiplexing.

See the Proactor pattern description at http://www.cs.wustl.edu/~schmidt/proactor.ps.gz for more details.


Member Typedef Documentation

You can add a hook to various run_event methods and the hook will be called after handling every proactor event. If this function returns 0, proactor_run_event_loop will check for the return value of handle_events. If it is -1, the the proactor_run_event_loop will return (pre-maturely.)


Constructor & Destructor Documentation

ACE_Proactor::ACE_Proactor ( ACE_Proactor_Impl implementation = 0,
bool  delete_implementation = false,
ACE_Proactor_Timer_Queue tq = 0 
)

Constructor. If implementation is 0, the correct implementation object will be created. delete_implementation flag determines whether the implementation object should be deleted by the Proactor or not. If tq is 0, a new TIMER_QUEUE is created.

Destruction.

ACE_Proactor::ACE_Proactor ( const ACE_Proactor ) [private]

Deny access since member-wise won't work...


Member Function Documentation

int ACE_Proactor::cancel_timer ( ACE_Handler handler,
int  dont_call_handle_close = 1 
)

Cancel all timers associated with this handler. Returns number of timers cancelled.

int ACE_Proactor::cancel_timer ( long  timer_id,
const void **  act = 0,
int  dont_call_handle_close = 1 
)

Cancel the single <ACE_Handler> that matches the timer_id value (which was returned from the <schedule> method). If act is non-NULL then it will be set to point to the ``magic cookie'' argument passed in when the <Handler> was registered. This makes it possible to free up the memory and avoid memory leaks. Returns 1 if cancellation succeeded and 0 if the timer_id wasn't found.

The singleton proactor is used by the ACE_Service_Config. Therefore, we must check for the reconfiguration request and handle it after handling an event.

static void ACE_Proactor::cleanup ( void *  instance,
void *  arg 
) [static]

Cleanup method, used by the ACE_Object_Manager to destroy the singleton.

int ACE_Proactor::close ( void  )

Close the associated ACE_Proactor_Impl implementation object.

If

  • delete_implementation was specified to the open() method, the implementation object is also deleted.

Close all dispatch threads.

void ACE_Proactor::close_singleton ( void  ) [static]

Delete the dynamically allocated Singleton.

Create the correct implementation class for doing Asynch_Accept.

ACE_Asynch_Accept_Result_Impl * ACE_Proactor::create_asynch_accept_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  listen_handle,
ACE_HANDLE  accept_handle,
ACE_Message_Block message_block,
u_long  bytes_to_read,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Accept::Result.

Create the correct implementation class for doing Asynch_Connect.

ACE_Asynch_Connect_Result_Impl * ACE_Proactor::create_asynch_connect_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  connect_handle,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Connect::Result.

Create the correct implementation class for doing Asynch_Read_Dgram.

ACE_Asynch_Read_Dgram_Result_Impl * ACE_Proactor::create_asynch_read_dgram_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
ACE_Message_Block message_block,
size_t  bytes_to_read,
int  flags,
int  protocol_family,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Read_Dgram::Result.

Create the correct implementation class for doing Asynch_Read_File.

ACE_Asynch_Read_File_Result_Impl * ACE_Proactor::create_asynch_read_file_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
ACE_Message_Block message_block,
u_long  bytes_to_read,
const void *  act,
u_long  offset,
u_long  offset_high,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Read_File::Result.

Create the correct implementation class for doing Asynch_Read_Stream.

ACE_Asynch_Read_Stream_Result_Impl * ACE_Proactor::create_asynch_read_stream_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
ACE_Message_Block message_block,
u_long  bytes_to_read,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Read_Stream::Result class.

ACE_Asynch_Result_Impl * ACE_Proactor::create_asynch_timer ( ACE_Handler::Proxy_Ptr handler_proxy,
const void *  act,
const ACE_Time_Value tv,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create a timer result object which can be used with the Timer mechanism of the Proactor. If signal_number is -1, <POSIX_SIG_Proactor> will create a Timer object with a meaningful signal number, choosing the largest signal number from the signal mask of the Proactor.

Create the correct implementation class for doing Asynch_Transmit_File.

ACE_Asynch_Transmit_File_Result_Impl * ACE_Proactor::create_asynch_transmit_file_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  socket,
ACE_HANDLE  file,
ACE_Asynch_Transmit_File::Header_And_Trailer header_and_trailer,
u_long  bytes_to_write,
u_long  offset,
u_long  offset_high,
u_long  bytes_per_send,
u_long  flags,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Transmit_File::Result.

Create the correct implementation class for doing Asynch_Write_Dgram.

ACE_Asynch_Write_Dgram_Result_Impl * ACE_Proactor::create_asynch_write_dgram_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
ACE_Message_Block message_block,
size_t  bytes_to_write,
int  flags,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Write_Dgram::Result.

Create the correct implementation class for doing Asynch_Write_File.

ACE_Asynch_Write_File_Result_Impl * ACE_Proactor::create_asynch_write_file_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
ACE_Message_Block message_block,
u_long  bytes_to_write,
const void *  act,
u_long  offset,
u_long  offset_high,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Write_File::Result.

Create the correct implementation class for doing Asynch_Write_Stream.

ACE_Asynch_Write_Stream_Result_Impl * ACE_Proactor::create_asynch_write_stream_result ( ACE_Handler::Proxy_Ptr handler_proxy,
ACE_HANDLE  handle,
ACE_Message_Block message_block,
u_long  bytes_to_write,
const void *  act,
ACE_HANDLE  event = ACE_INVALID_HANDLE,
int  priority = 0,
int  signal_number = ACE_SIGRTMIN 
)

Create the correct implementation class for ACE_Asynch_Write_Stream::Result.

const ACE_TCHAR * ACE_Proactor::dll_name ( void  ) [static]

Name of dll in which the singleton instance lives.

int ACE_Proactor::end_event_loop ( void  ) [inline, static]

Instruct the <ACE_Proactor::instance> to terminate its event loop. This method wakes up all the threads blocked on waiting for completions and end the event loop.

int ACE_Proactor::event_loop_done ( void  ) [inline, static]

Report if the <ACE_Proactor::instance> event loop is finished.

ACE_HANDLE ACE_Proactor::get_handle ( void  ) const

Get the event handle. It is a no-op in POSIX platforms and it returns ACE_INVALID_HANDLE.

Dispatch a single set of events, waiting up to a specified time limit if necessary.

Parameters:
wait_timethe time to wait for an event to occur. This is a relative time. On successful return, the time is updated to reflect the amount of time spent waiting for event(s) to occur.
Returns:
Returns 0 if no events occur before the wait_time expires. Returns 1 when a completion is dispatched. On error, returns -1 and sets errno accordingly.

Block indefinitely until at least one event is dispatched.

Returns:
Returns 1 when a completion is dispatched. On error, returns -1 and sets errno accordingly.

Get the implementation class.

void ACE_Proactor::implementation ( ACE_Proactor_Impl implementation) [protected]

Set the implementation class.

ACE_Proactor * ACE_Proactor::instance ( size_t  threads = 0) [static]

Get pointer to a process-wide ACE_Proactor. threads should be part of another method.

ACE_Proactor * ACE_Proactor::instance ( ACE_Proactor proactor,
bool  delete_proactor = false 
) [static]

Set pointer to a process-wide ACE_Proactor and return existing pointer.

const ACE_TCHAR * ACE_Proactor::name ( void  ) [static]

Name of component--ACE_Proactor in this case.

size_t ACE_Proactor::number_of_threads ( void  ) const

Get number of thread used as a parameter to CreatIoCompletionPort.

void ACE_Proactor::number_of_threads ( size_t  threads)

Set number of thread used as a parameter to CreatIoCompletionPort.

ACE_Proactor& ACE_Proactor::operator= ( const ACE_Proactor ) [private]
int ACE_Proactor::post_wakeup_completions ( int  how_many) [inline, static, protected]

Post <how_many> completions to the completion port so that all threads can wake up. This is used in conjunction with the <run_event_loop>.

Instruct the ACE_Proactor to terminate its event loop and notifies the ACE_Proactor so that it can wake up and close down gracefully.

Report if the ACE_Proactor event loop is finished.

int ACE_Proactor::proactor_post_wakeup_completions ( int  how_many) [protected]

Post <how_many> completions to the completion port so that all threads can wake up. This is used in conjunction with the <proactor_run_event_loop>.

Resets the <ACE_Proactor::end_event_loop_> static so that the <run_event_loop> method can be restarted.

Run the event loop until the <ACE_Proactor::handle_events> method returns -1 or the <end_proactor_event_loop> method is invoked.

Run the event loop until the <ACE_Proactor::handle_events> method returns -1, the <end_proactor_event_loop> method is invoked, or the ACE_Time_Value expires, in which case a 0 is returned.

int ACE_Proactor::register_handle ( ACE_HANDLE  handle,
const void *  completion_key 
)

This method adds the handle to the I/O completion port. This function is a no-op function for Unix systems and returns 0;

int ACE_Proactor::reset_event_loop ( void  ) [inline, static]

Resets the <ACE_Proactor::end_event_loop_> static so that the <run_event_loop> method can be restarted.

int ACE_Proactor::run_event_loop ( void  ) [inline, static]

Run the event loop until the <ACE_Proactor::handle_events> method returns -1 or the <end_event_loop> method is invoked.

int ACE_Proactor::run_event_loop ( ACE_Time_Value tv) [inline, static]

Run the event loop until the <ACE_Proactor::handle_events> method returns -1, the <end_event_loop> method is invoked, or the ACE_Time_Value expires, in which case 0 is returned.

long ACE_Proactor::schedule_repeating_timer ( ACE_Handler handler,
const void *  act,
const ACE_Time_Value interval 
)
long ACE_Proactor::schedule_timer ( ACE_Handler handler,
const void *  act,
const ACE_Time_Value time 
)

Schedule a handler that will expire after <time>. If it expires then act is passed in as the value to the handler's <handle_timeout> callback method. This method returns a <timer_id>. This <timer_id> can be used to cancel a timer before it expires. The cancellation ensures that <timer_ids> are unique up to values of greater than 2 billion timers. As long as timers don't stay around longer than this there should be no problems with accidentally deleting the wrong timer. Returns -1 on failure (which is guaranteed never to be a valid <timer_id>).

long ACE_Proactor::schedule_timer ( ACE_Handler handler,
const void *  act,
const ACE_Time_Value time,
const ACE_Time_Value interval 
)

Same as above except interval it is used to reschedule the handler automatically. This combines the above two methods into one. Mostly for backward compatibility.

Get timer queue.

Set timer queue.

Add wakeup dispatch threads (reinit).


Friends And Related Function Documentation

friend class ACE_Proactor_Timer_Handler [friend]

Timer handler runs a thread and manages the timers, on behalf of the Proactor.


Member Data Documentation

Flag used to indicate whether we are responsible for cleaning up the implementation instance.

bool ACE_Proactor::delete_proactor_ = false [static, protected]

Must delete the <proactor_> if true.

Controls whether the Proactor is deleted when we shut down (we can only delete it safely if we created it!)

Flag on whether to delete the timer queue.

Terminate the proactor event loop.

Number of threads in the event loop.

Delegation/implementation class that all methods will be forwarded to.

Mutex to protect work with lists.

ACE_Proactor * ACE_Proactor::proactor_ = 0 [static, protected]

Pointer to a process-wide ACE_Proactor.

Process-wide ACE_Proactor.

This will manage the thread in the Timer_Handler.

Handles timeout events.

Timer Queue.


The documentation for this class was generated from the following files: