~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to erts/emulator/sys/common/erl_check_io.c

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-08-05 20:54:29 UTC
  • mfrom: (6.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20090805205429-pm4pnwew8axraosl
Tags: 1:13.b.1-dfsg-5
* Fixed parentheses in Emacs mode (closes: #536891).
* Removed unnecessary conflicts with erlang-manpages package.
* Added workaround for #475459: disabled threads on sparc architecture.
  This breaks wxErlang, so it's only a temporary solution.

Show diffs side-by-side

added added

removed removed

Lines of Context:
104
104
#ifdef ERTS_SMP
105
105
struct removed_fd {
106
106
    struct removed_fd *next;
 
107
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
 
108
    ErtsSysFdType fd;
 
109
#else
107
110
    ErtsDrvEventState* state;
108
 
#ifdef DEBUG
 
111
    #ifdef DEBUG
109
112
    ErtsSysFdType fd;
 
113
    #endif
110
114
#endif
 
115
 
111
116
};
112
117
#endif
113
118
 
166
171
 
167
172
static ERTS_INLINE void hash_erase_drv_ev_state(ErtsDrvEventState *state)
168
173
{
 
174
    ASSERT(state->remove_cnt == 0);
169
175
    safe_hash_erase(&drv_ev_state_tab, (void *) state);
170
176
}
171
177
 
216
222
        state->remove_cnt++;
217
223
        ASSERT(state->remove_cnt > 0);
218
224
        fdlp = removed_fd_alloc();
 
225
    #if defined(ERTS_SYS_CONTINOUS_FD_NUMBERS) || defined(DEBUG)
 
226
        fdlp->fd = state->fd;
 
227
    #endif
 
228
    #ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS
219
229
        fdlp->state = state;
220
 
#ifdef DEBUG
221
 
        fdlp->fd = state->fd;
222
 
#endif
 
230
    #endif
223
231
        erts_smp_spin_lock(&psi->removed_list_lock);
224
232
        fdlp->next = psi->removed_list;
225
233
        psi->removed_list = fdlp;
244
252
#endif
245
253
}
246
254
 
247
 
 
248
255
static void
249
256
forget_removed(struct pollset_info* psi)
250
257
{
263
270
        erts_driver_t* drv_ptr = NULL;
264
271
        erts_smp_mtx_t* mtx;
265
272
        ErtsSysFdType fd;
266
 
        ErtsDrvEventState *state = fdlp->state; 
267
 
        ASSERT(state);
 
273
        ErtsDrvEventState *state;
 
274
 
 
275
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
 
276
        fd = fdlp->fd;
 
277
        mtx = fd_mtx(fd);
 
278
        erts_smp_mtx_lock(mtx);
 
279
        state = &drv_ev_state[(int) fd];
 
280
#else
 
281
        state = fdlp->state;
268
282
        fd = state->fd;
269
283
        ASSERT(fd == fdlp->fd);
270
284
        mtx = fd_mtx(fd);
271
285
        erts_smp_mtx_lock(mtx);
 
286
#endif
272
287
        ASSERT(state->remove_cnt > 0);
273
288
        if (--state->remove_cnt == 0) {
274
289
            switch (state->type) {
455
470
    }
456
471
}
457
472
 
 
473
 
 
474
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
 
475
#  define IS_FD_UNKNOWN(state) ((state)->type == ERTS_EV_TYPE_NONE && (state)->remove_cnt == 0)
 
476
#else
 
477
#  define IS_FD_UNKNOWN(state) ((state) == NULL)
 
478
#endif
 
479
 
 
480
 
458
481
int
459
482
ERTS_CIO_EXPORT(driver_select)(ErlDrvPort ix,
460
483
                               ErlDrvEvent e,
469
492
    ErtsDrvEventState *state;
470
493
    int wake_poller;
471
494
    int ret;
472
 
 
 
495
    
473
496
    ERTS_SMP_LC_ASSERT(erts_drvport2port(ix)
474
497
                       && erts_lc_is_port_locked(erts_drvport2port(ix)));
475
498
 
476
499
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
477
500
    if ((unsigned)fd >= (unsigned)erts_smp_atomic_read(&drv_ev_state_len)) {
478
 
        if (fd < 0)
 
501
        if (fd < 0) {
479
502
            return -1;    
 
503
        }
480
504
        if (fd >= max_fds) {
481
505
            select_large_fd_error(ix, fd, mode, on);
482
506
            return -1;
485
509
    }
486
510
#endif
487
511
 
 
512
    erts_smp_mtx_lock(fd_mtx(fd));
 
513
 
 
514
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
 
515
    state = &drv_ev_state[(int) fd];
 
516
#else
 
517
    state = hash_get_drv_ev_state(fd); /* may be NULL! */
 
518
#endif
 
519
 
488
520
    if (!on && (mode&ERL_DRV_USE_NO_CALLBACK) == ERL_DRV_USE) {
 
521
        if (IS_FD_UNKNOWN(state)) {
 
522
            /* fast track to stop_select callback */
 
523
            stop_select_fn = erts_drvport2port(ix)->drv_ptr->stop_select;
 
524
            ret = 0;
 
525
            goto done_unknown;
 
526
        }
489
527
        mode |= (ERL_DRV_READ | ERL_DRV_WRITE);
490
528
        wake_poller = 1; /* to eject fd from pollset (if needed) */
491
529
    }
492
530
    else wake_poller = 0;
493
531
 
494
 
    erts_smp_mtx_lock(fd_mtx(fd));
495
 
 
496
 
#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS
497
 
    state = &drv_ev_state[(int) fd];
498
 
#else
499
 
    /* Could use hash_new directly, but want to keep the normal case fast */
500
 
    state = hash_get_drv_ev_state(fd);
 
532
#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS
501
533
    if (state == NULL) {
502
534
        state = hash_new_drv_ev_state(fd);
503
535
    }
538
570
    ASSERT((state->type == ERTS_EV_TYPE_DRV_SEL) ||
539
571
           (state->type == ERTS_EV_TYPE_NONE && !state->events));
540
572
 
541
 
    if (!on && state->events && !(state->events & ~ctl_events) &&
542
 
        !(state->flags & ERTS_EV_FLAG_USED)) {
543
 
        /* Old driver remove all events. At least wake poller.
 
573
    if (!on && !(state->flags & ERTS_EV_FLAG_USED) 
 
574
        && state->events && !(state->events & ~ctl_events)) {   
 
575
        /* Old driver removing all events. At least wake poller.
544
576
           It will not make close() 100% safe but it will prevent
545
577
           actions delayed by poll timeout. */
546
578
        wake_poller = 1;
605
637
                if (new_events == 0) {
606
638
                    ASSERT(!erts_port_task_is_scheduled(&state->driver.select->intask));
607
639
                    ASSERT(!erts_port_task_is_scheduled(&state->driver.select->outtask));
608
 
                    remember_removed(state, &pollset);
609
 
                    
 
640
                    if (old_events != 0) {
 
641
                        remember_removed(state, &pollset);
 
642
                    }               
610
643
                    if ((mode & ERL_DRV_USE) || !(state->flags & ERTS_EV_FLAG_USED)) {
611
644
                        state->type = ERTS_EV_TYPE_NONE;
612
645
                        state->flags = 0;
639
672
   
640
673
    ret = 0;
641
674
 
642
 
done:
 
675
done:;
643
676
#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS
644
677
    if (state->type == ERTS_EV_TYPE_NONE && state->remove_cnt == 0) {
645
678
        hash_erase_drv_ev_state(state);
646
679
    }
647
680
#endif
 
681
done_unknown:    
648
682
    erts_smp_mtx_unlock(fd_mtx(fd));
649
683
    if (stop_select_fn) {
650
684
        int was_unmasked = erts_block_fpe();