~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/os/os0file.c

Tags: innodb-plugin-1.0.2
InnoDB Plugin 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <errno.h>
23
23
#endif /* UNIV_HOTBACKUP */
24
24
 
25
 
#ifdef POSIX_ASYNC_IO
26
 
/* We assume in this case that the OS has standard Posix aio (at least SunOS
27
 
2.6, HP-UX 11i and AIX 4.3 have) */
28
 
 
29
 
#endif
30
 
 
31
25
/* This specifies the file permissions InnoDB uses when it creates files in
32
26
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
33
27
my_umask */
96
90
                                        OVERLAPPED struct */
97
91
        OVERLAPPED      control;        /* Windows control block for the
98
92
                                        aio request */
99
 
#elif defined(POSIX_ASYNC_IO)
100
 
        struct aiocb    control;        /* Posix control block for aio
101
 
                                        request */
102
93
#endif
103
94
};
104
95
 
331
322
 
332
323
        if (err == ENOSPC) {
333
324
                return(OS_FILE_DISK_FULL);
334
 
#ifdef POSIX_ASYNC_IO
335
 
        } else if (err == EAGAIN) {
336
 
                return(OS_FILE_AIO_RESOURCES_RESERVED);
337
 
#endif
338
325
        } else if (err == ENOENT) {
339
326
                return(OS_FILE_NOT_FOUND);
340
327
        } else if (err == EEXIST) {
1254
1241
        if (file == INVALID_HANDLE_VALUE) {
1255
1242
                *success = FALSE;
1256
1243
 
1257
 
                retry = os_file_handle_error(name,
1258
 
                                             create_mode == OS_FILE_CREATE ?
1259
 
                                             "create" : "open");
 
1244
                /* When srv_file_per_table is on, file creation failure may not
 
1245
                be critical to the whole instance. Do not crash the server in
 
1246
                case of unknown errors. */
 
1247
                if (srv_file_per_table) {
 
1248
                        retry = os_file_handle_error_no_exit(name,
 
1249
                                                create_mode == OS_FILE_CREATE ?
 
1250
                                                "create" : "open");
 
1251
                } else {
 
1252
                        retry = os_file_handle_error(name,
 
1253
                                                create_mode == OS_FILE_CREATE ?
 
1254
                                                "create" : "open");
 
1255
                }
 
1256
 
1260
1257
                if (retry) {
1261
1258
                        goto try_again;
1262
1259
                }
1331
1328
        if (file == -1) {
1332
1329
                *success = FALSE;
1333
1330
 
1334
 
                retry = os_file_handle_error(name,
1335
 
                                             create_mode == OS_FILE_CREATE ?
1336
 
                                             "create" : "open");
 
1331
                /* When srv_file_per_table is on, file creation failure may not
 
1332
                be critical to the whole instance. Do not crash the server in
 
1333
                case of unknown errors. */
 
1334
                if (srv_file_per_table) {
 
1335
                        retry = os_file_handle_error_no_exit(name,
 
1336
                                                create_mode == OS_FILE_CREATE ?
 
1337
                                                "create" : "open");
 
1338
                } else {
 
1339
                        retry = os_file_handle_error(name,
 
1340
                                                create_mode == OS_FILE_CREATE ?
 
1341
                                                "create" : "open");
 
1342
                }
 
1343
 
1337
1344
                if (retry) {
1338
1345
                        goto try_again;
1339
1346
                } else {
2921
2928
        ulint   n_write_segs;
2922
2929
        ulint   n_per_seg;
2923
2930
        ulint   i;
2924
 
#ifdef POSIX_ASYNC_IO
2925
 
        sigset_t   sigset;
2926
 
#endif
 
2931
 
2927
2932
        ut_ad(n % n_segments == 0);
2928
2933
        ut_ad(n_segments >= 4);
2929
2934
 
2975
2980
 
2976
2981
        os_last_printout = time(NULL);
2977
2982
 
2978
 
#ifdef POSIX_ASYNC_IO
2979
 
        /* Block aio signals from the current thread and its children:
2980
 
        for this to work, the current thread must be the first created
2981
 
        in the database, so that all its children will inherit its
2982
 
        signal mask */
2983
 
 
2984
 
        /* TODO: to work MySQL needs the SIGALARM signal; the following
2985
 
        will not work yet! */
2986
 
        sigemptyset(&sigset);
2987
 
        sigaddset(&sigset, SIGRTMIN + 1 + 0);
2988
 
        sigaddset(&sigset, SIGRTMIN + 1 + 1);
2989
 
        sigaddset(&sigset, SIGRTMIN + 1 + 2);
2990
 
        sigaddset(&sigset, SIGRTMIN + 1 + 3);
2991
 
 
2992
 
        pthread_sigmask(SIG_BLOCK, &sigset, NULL); */
2993
 
#endif
2994
 
                }
 
2983
}
2995
2984
 
2996
2985
#ifdef WIN_ASYNC_IO
2997
2986
/****************************************************************************
3122
3111
}
3123
3112
 
3124
3113
/***********************************************************************
3125
 
Gets an integer value designating a specified aio array. This is used
3126
 
to give numbers to signals in Posix aio. */
3127
 
 
3128
 
#if !defined(WIN_ASYNC_IO) && defined(POSIX_ASYNC_IO)
3129
 
static
3130
 
ulint
3131
 
os_aio_get_array_no(
3132
 
/*================*/
3133
 
        os_aio_array_t* array)  /* in: aio array */
3134
 
{
3135
 
        if (array == os_aio_ibuf_array) {
3136
 
 
3137
 
                return(0);
3138
 
 
3139
 
        } else if (array == os_aio_log_array) {
3140
 
 
3141
 
                return(1);
3142
 
 
3143
 
        } else if (array == os_aio_read_array) {
3144
 
 
3145
 
                return(2);
3146
 
        } else if (array == os_aio_write_array) {
3147
 
 
3148
 
                return(3);
3149
 
        } else {
3150
 
                ut_error;
3151
 
 
3152
 
                return(0);
3153
 
        }
3154
 
}
3155
 
 
3156
 
/***********************************************************************
3157
 
Gets the aio array for its number. */
3158
 
static
3159
 
os_aio_array_t*
3160
 
os_aio_get_array_from_no(
3161
 
/*=====================*/
3162
 
                        /* out: aio array */
3163
 
        ulint   n)      /* in: array number */
3164
 
{
3165
 
        if (n == 0) {
3166
 
                return(os_aio_ibuf_array);
3167
 
        } else if (n == 1) {
3168
 
 
3169
 
                return(os_aio_log_array);
3170
 
        } else if (n == 2) {
3171
 
 
3172
 
                return(os_aio_read_array);
3173
 
        } else if (n == 3) {
3174
 
 
3175
 
                return(os_aio_write_array);
3176
 
        } else {
3177
 
                ut_error;
3178
 
 
3179
 
                return(NULL);
3180
 
        }
3181
 
}
3182
 
#endif /* if !defined(WIN_ASYNC_IO) && defined(POSIX_ASYNC_IO) */
3183
 
 
3184
 
/***********************************************************************
3185
3114
Requests for a slot in the aio array. If no slot is available, waits until
3186
3115
not_full-event becomes signaled. */
3187
3116
static
3209
3138
        os_aio_slot_t*  slot;
3210
3139
#ifdef WIN_ASYNC_IO
3211
3140
        OVERLAPPED*     control;
3212
 
 
3213
 
#elif defined(POSIX_ASYNC_IO)
3214
 
 
3215
 
        struct aiocb*   control;
3216
3141
#endif
3217
3142
        ulint           i;
3218
3143
loop:
3269
3194
        control->Offset = (DWORD)offset;
3270
3195
        control->OffsetHigh = (DWORD)offset_high;
3271
3196
        os_event_reset(slot->event);
3272
 
 
3273
 
#elif defined(POSIX_ASYNC_IO)
3274
 
 
3275
 
#if (UNIV_WORD_SIZE == 8)
3276
 
        offset = offset + (offset_high << 32);
3277
 
#else
3278
 
        ut_a(offset_high == 0);
3279
 
#endif
3280
 
        control = &(slot->control);
3281
 
        control->aio_fildes = file;
3282
 
        control->aio_buf = buf;
3283
 
        control->aio_nbytes = len;
3284
 
        control->aio_offset = offset;
3285
 
        control->aio_reqprio = 0;
3286
 
        control->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
3287
 
        control->aio_sigevent.sigev_signo
3288
 
                = SIGRTMIN + 1 + os_aio_get_array_no(array);
3289
 
        /* TODO: How to choose the signal numbers? */
3290
 
        /*
3291
 
        fprintf(stderr, "AIO signal number %lu\n",
3292
 
        (ulint) control->aio_sigevent.sigev_signo);
3293
 
        */
3294
 
        control->aio_sigevent.sigev_value.sival_ptr = slot;
3295
 
#endif
 
3197
#endif
 
3198
 
3296
3199
        os_mutex_exit(array->mutex);
3297
3200
 
3298
3201
        return(slot);
3540
3443
 
3541
3444
                        ret = ReadFile(file, buf, (DWORD)n, &len,
3542
3445
                                       &(slot->control));
3543
 
#elif defined(POSIX_ASYNC_IO)
3544
 
                        slot->control.aio_lio_opcode = LIO_READ;
3545
 
                        err = (ulint) aio_read(&(slot->control));
3546
 
                        fprintf(stderr, "Starting POSIX aio read %lu\n", err);
3547
3446
#endif
3548
3447
                } else {
3549
3448
                        if (!wake_later) {
3558
3457
                        os_n_file_writes++;
3559
3458
                        ret = WriteFile(file, buf, (DWORD)n, &len,
3560
3459
                                        &(slot->control));
3561
 
#elif defined(POSIX_ASYNC_IO)
3562
 
                        slot->control.aio_lio_opcode = LIO_WRITE;
3563
 
                        err = (ulint) aio_write(&(slot->control));
3564
 
                        fprintf(stderr, "Starting POSIX aio write %lu\n", err);
3565
3460
#endif
3566
3461
                } else {
3567
3462
                        if (!wake_later) {
3706
3601
        if (ret && len == slot->len) {
3707
3602
                ret_val = TRUE;
3708
3603
 
3709
 
# ifdef UNIV_DO_FLUSH
 
3604
#ifdef UNIV_DO_FLUSH
3710
3605
                if (slot->type == OS_FILE_WRITE
3711
3606
                    && !os_do_not_call_flush_at_each_write) {
3712
3607
                        ut_a(TRUE == os_file_flush(slot->file));
3713
3608
                }
3714
 
# endif /* UNIV_DO_FLUSH */
 
3609
#endif /* UNIV_DO_FLUSH */
3715
3610
        } else {
3716
3611
                os_file_handle_error(slot->name, "Windows aio");
3717
3612
 
3726
3621
}
3727
3622
#endif
3728
3623
 
3729
 
#ifdef POSIX_ASYNC_IO
3730
 
 
3731
 
/**************************************************************************
3732
 
This function is only used in Posix asynchronous i/o. Waits for an aio
3733
 
operation to complete. */
3734
 
UNIV_INTERN
3735
 
ibool
3736
 
os_aio_posix_handle(
3737
 
/*================*/
3738
 
                                /* out: TRUE if the aio operation succeeded */
3739
 
        ulint   array_no,       /* in: array number 0 - 3 */
3740
 
        fil_node_t**message1,   /* out: the messages passed with the aio
3741
 
                                request; note that also in the case where
3742
 
                                the aio operation failed, these output
3743
 
                                parameters are valid and can be used to
3744
 
                                restart the operation, for example */
3745
 
        void**  message2)
3746
 
{
3747
 
        os_aio_array_t* array;
3748
 
        os_aio_slot_t*  slot;
3749
 
        siginfo_t       info;
3750
 
        sigset_t        sigset;
3751
 
        sigset_t        proc_sigset;
3752
 
        sigset_t        thr_sigset;
3753
 
        int             ret;
3754
 
        int             i;
3755
 
        int             sig;
3756
 
 
3757
 
        sigemptyset(&sigset);
3758
 
        sigaddset(&sigset, SIGRTMIN + 1 + array_no);
3759
 
 
3760
 
        pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
3761
 
 
3762
 
#if 0
3763
 
        sigprocmask(0, NULL, &proc_sigset);
3764
 
        pthread_sigmask(0, NULL, &thr_sigset);
3765
 
 
3766
 
        for (i = 32 ; i < 40; i++) {
3767
 
                fprintf(stderr, "%lu : %lu %lu\n", (ulint)i,
3768
 
                        (ulint) sigismember(&proc_sigset, i),
3769
 
                        (ulint) sigismember(&thr_sigset, i));
3770
 
        }
3771
 
#endif
3772
 
 
3773
 
        ret = sigwaitinfo(&sigset, &info);
3774
 
 
3775
 
        if (sig != SIGRTMIN + 1 + array_no) {
3776
 
 
3777
 
                ut_error;
3778
 
 
3779
 
                return(FALSE);
3780
 
        }
3781
 
 
3782
 
        fputs("Handling POSIX aio\n", stderr);
3783
 
 
3784
 
        array = os_aio_get_array_from_no(array_no);
3785
 
 
3786
 
        os_mutex_enter(array->mutex);
3787
 
 
3788
 
        slot = info.si_value.sival_ptr;
3789
 
 
3790
 
        ut_a(slot->reserved);
3791
 
 
3792
 
        *message1 = slot->message1;
3793
 
        *message2 = slot->message2;
3794
 
 
3795
 
# ifdef UNIV_DO_FLUSH
3796
 
        if (slot->type == OS_FILE_WRITE
3797
 
            && !os_do_not_call_flush_at_each_write) {
3798
 
                ut_a(TRUE == os_file_flush(slot->file));
3799
 
        }
3800
 
# endif /* UNIV_DO_FLUSH */
3801
 
 
3802
 
        os_mutex_exit(array->mutex);
3803
 
 
3804
 
        os_aio_array_free_slot(array, slot);
3805
 
 
3806
 
        return(TRUE);
3807
 
}
3808
 
#endif
3809
 
 
3810
3624
/**************************************************************************
3811
3625
Does simulated aio. This function should be called by an i/o-handler
3812
3626
thread. */