/*

  sshoperation.c

  Author: Tero Kivinen <kivinen@ssh.fi>
          Timo J. Rinne <tri@ssh.fi>

  Copyright (c) 1999 SSH Communications Security
                     All rights reserved

  Generic asynchronous call interface.  Registering, aborting and finishing
  asynchronous calls.

*/

/*
 * $Id: sshoperation.c,v 1.1 1999/10/20 17:30:08 huima Exp $
 * $Log: sshoperation.c,v $
 * $EndLog$
 */

#include "sshincludes.h"
#include "sshoperation.h"

struct SshOperationHandleRec {
  SshOperationAbortCB abort_cb;
  void *operation_context;
};



/* Register started asynchronous call and corresponding abort callback. This
   call is called by the function that starts the real operation, and the
   handle must be returned to the caller of the function, so it can then abort
   the operation using the ssh_operation_abort. */
SshOperationHandle ssh_operation_register(SshOperationAbortCB abort_cb,
                                          void *operation_context)
{
  SshOperationHandle handle;

  handle = ssh_xcalloc(1, sizeof(*handle));
  handle->abort_cb = abort_cb;
  handle->operation_context = operation_context;
  return handle;
}

/* Unregister the handle. The abort callback will not be called, and the handle
   is invalid after this (i.e any other part of the code must not call
   ssh_operation_abort using the handle). */
void ssh_operation_unregister(SshOperationHandle handle)
{
  ssh_xfree(handle);
}

/* Return operation context pointer from the given operation handle. */
void *ssh_operation_get_context(SshOperationHandle handle)
{
  return handle->operation_context;
}

/* Call abort callback of the pending asynchronous call. The abort callback
   will then abort the operation if it is possible, and free the context
   associated to it. Note, after this call then, the handle is invalid, and no
   other calls can be made using it. The abort callback will also make sure
   that no other callbacks are called associated with this asynchronous call.
   */
void ssh_operation_abort(SshOperationHandle handle)
{
  if (handle != NULL)
    {
      (*handle->abort_cb)(handle->operation_context);
      ssh_xfree(handle);
    }
}

/* eof (sshoperation.c) */

