Commit f4da39d2 authored by Matt Caswell's avatar Matt Caswell
Browse files

Initial Async notify code changes



Initial API implemented for notifying applications that an ASYNC_JOB
has completed. Currently only s_server is using this. The Dummy Async
engine "cheats" in that it notifies that it has completed *before* it
pauses the job. A normal async engine would not do that.

Only the posix version of this has been implemented so far, so it will
probably fail to compile on Windows at the moment.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent 252d6d3a
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ typedef unsigned int u_int;
static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength);
#endif
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
static void wait_for_async(SSL *s);
static int sv_body(char *hostname, int s, int stype, unsigned char *context);
static int www_body(char *hostname, int s, int stype, unsigned char *context);
static int rev_body(char *hostname, int s, int stype, unsigned char *context);
@@ -2007,6 +2008,21 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
               SSL_CTX_sess_get_cache_size(ssl_ctx));
}

static void wait_for_async(SSL *s)
{
    int width, fd;
    fd_set asyncfds;

    fd = SSL_get_async_wait_fd(s);
    if (!fd)
        return;

    width = fd + 1;
    FD_ZERO(&asyncfds);
    openssl_fdset(fd, &asyncfds);
    select(width, (void *)&asyncfds, NULL, NULL, NULL);
}

static int sv_body(char *hostname, int s, int stype, unsigned char *context)
{
    char *buf = NULL;
@@ -2302,6 +2318,7 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context)
                    break;
                case SSL_ERROR_WANT_ASYNC:
                    BIO_printf(bio_s_out, "Write BLOCK (Async)\n");
                    wait_for_async(con);
                    break;
                case SSL_ERROR_WANT_WRITE:
                case SSL_ERROR_WANT_READ:
@@ -2368,6 +2385,9 @@ static int sv_body(char *hostname, int s, int stype, unsigned char *context)
                        goto again;
                    break;
                case SSL_ERROR_WANT_ASYNC:
                    BIO_printf(bio_s_out, "Read BLOCK (Async)\n");
                    wait_for_async(con);
                    break;
                case SSL_ERROR_WANT_WRITE:
                case SSL_ERROR_WANT_READ:
                    BIO_printf(bio_s_out, "Read BLOCK\n");
+26 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#ifdef ASYNC_SYSV
# include <stddef.h>
# include <ucontext.h>
# include <unistd.h>
# include <openssl/crypto.h>
# include <openssl/async.h>

@@ -85,4 +86,29 @@ void ASYNC_FIBRE_free(ASYNC_FIBRE *fibre)
    if (fibre->fibre.uc_stack.ss_sp)
        OPENSSL_free(fibre->fibre.uc_stack.ss_sp);
}

int async_pipe(int *pipefds)
{
    if (pipe(pipefds) == 0)
        return 1;

    return 0;
}

int async_write1(int fd, const void *buf)
{
    if (write(fd, buf, 1) > 0)
        return 1;

    return 0;
}

int async_read1(int fd, void *buf)
{
    if (read(fd, buf, 1) > 0)
        return 1;

    return 0;
}

#endif
+5 −0
Original line number Diff line number Diff line
@@ -99,5 +99,10 @@ static inline int ASYNC_FIBRE_swapcontext(ASYNC_FIBRE *o, ASYNC_FIBRE *n, int r)
int ASYNC_FIBRE_init(ASYNC_FIBRE *fibre);
void ASYNC_FIBRE_free(ASYNC_FIBRE *fibre);

int async_pipe(int *pipefds);
int async_write1(int fd, const void *buf);
int async_read1(int fd, void *buf);


# endif
#endif
+43 −0
Original line number Diff line number Diff line
@@ -106,11 +106,21 @@ static int ASYNC_CTX_free(void)
static ASYNC_JOB *ASYNC_JOB_new(void)
{
    ASYNC_JOB *job = NULL;
    int pipefds[2];

    if(!(job = OPENSSL_malloc(sizeof (ASYNC_JOB)))) {
        return NULL;
    }

    if(!async_pipe(pipefds)) {
        OPENSSL_free(job);
        return NULL;
    }

    job->wake_set = 0;
    job->wait_fd = pipefds[0];
    job->wake_fd = pipefds[1];

    job->status = ASYNC_JOB_RUNNING;
    job->funcargs = NULL;

@@ -335,3 +345,36 @@ void ASYNC_free_pool(void)
    } while (job);
    sk_ASYNC_JOB_free(pool);
}

ASYNC_JOB *ASYNC_get_current_job(void)
{
    ASYNC_CTX *ctx;
    if((ctx = ASYNC_get_ctx()) == NULL)
        return NULL;

    return ctx->currjob;
}

int ASYNC_get_wait_fd(ASYNC_JOB *job)
{
    return job->wait_fd;
}

void ASYNC_wake(ASYNC_JOB *job)
{
    char dummy = 0;

    if (job->wake_set)
        return;
    async_write1(job->wake_fd, &dummy);
    job->wake_set = 1;
}

void ASYNC_clear_wake(ASYNC_JOB *job)
{
    char dummy = 0;
    if (!job->wake_set)
        return;
    async_read1(job->wait_fd, &dummy);
    job->wake_set = 0;
}
+3 −0
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ struct async_job_st {
    void *funcargs;
    int ret;
    int status;
    int wake_set;
    int wait_fd;
    int wake_fd;
};

void ASYNC_start_func(void);
Loading