X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fcommand.h;fp=apps%2Fsilcd%2Fcommand.h;h=9180768a213efafdd7a0a8b635a7c2c2f1897aea;hb=692b5f0e37647edafb7317ac1d3b164a6285194a;hp=de0b464b78d02f3fd28d93f0ee97ee26964ae64e;hpb=74debe93b0a49dac4d17bfff53b60a6c95e015cc;p=silc.git diff --git a/apps/silcd/command.h b/apps/silcd/command.h index de0b464b..9180768a 100644 --- a/apps/silcd/command.h +++ b/apps/silcd/command.h @@ -21,8 +21,6 @@ #ifndef COMMAND_H #define COMMAND_H -#include "command_reply.h" - /* Structure holding one command and pointer to its function. @@ -57,19 +55,30 @@ typedef struct { SilcArgumentPayload args; SilcPacketContext *packet; int pending; /* Command is being re-processed when TRUE */ + int users; /* Reference counter */ } *SilcServerCommandContext; +/* Pending Command callback destructor. This is called after calling the + pending callback or if error occurs while processing the pending command. + If error occurs then the callback won't be called at all, and only this + destructor is called. The `context' is the context given for the function + silc_server_command_pending. */ +typedef void (*SilcServerPendingDestructor)(void *context); + /* Structure holding pending commands. If command is pending it will be executed after command reply has been received and executed. */ typedef struct SilcServerCommandPendingStruct { SilcServer server; SilcCommand reply_cmd; SilcCommandCb callback; + SilcServerPendingDestructor destructor; void *context; unsigned short ident; struct SilcServerCommandPendingStruct *next; } SilcServerCommandPending; +#include "command_reply.h" + /* Macros */ /* Macro used for command declaration in command list structure */ @@ -81,21 +90,32 @@ typedef struct SilcServerCommandPendingStruct { void silc_server_command_##func(void *context) /* Executed pending command */ -#define SILC_SERVER_COMMAND_EXEC_PENDING(ctx, cmd) \ +#define SILC_SERVER_PENDING_EXEC(ctx, cmd) \ do { \ - if (ctx->callback) { \ + if (ctx->callback) \ (*ctx->callback)(ctx->context); \ - silc_server_command_pending_del(ctx->server, cmd, ctx->ident); \ - } \ +} while(0) + +/* Execute destructor for pending command */ +#define SILC_SERVER_PENDING_DESTRUCTOR(ctx, cmd) \ +do { \ + silc_server_command_pending_del(ctx->server, cmd, ctx->ident); \ + if (ctx->destructor) \ + (*ctx->destructor)(ctx->context); \ } while(0) /* Prototypes */ void silc_server_command_process(SilcServer server, SilcSocketConnection sock, SilcPacketContext *packet); +SilcServerCommandContext silc_server_command_alloc(); +void silc_server_command_free(SilcServerCommandContext ctx); +SilcServerCommandContext +silc_server_command_dup(SilcServerCommandContext ctx); void silc_server_command_pending(SilcServer server, SilcCommand reply_cmd, unsigned short ident, + SilcServerPendingDestructor destructor, SilcCommandCb callback, void *context); void silc_server_command_pending_del(SilcServer server,