--- kcapi.c.orig 2003-05-13 17:19:36.000000000 +0200 +++ kcapi.c 2003-05-13 17:19:46.000000000 +0200 @@ -73,7 +73,7 @@ struct capi_appl { __u16 applid; capi_register_params rparam; - int releasing; + atomic_t releasing; void *param; void (*signal) (__u16 applid, void *param); struct sk_buff_head recv_queue; @@ -705,8 +705,7 @@ nextpp = &(*pp)->next; } } - APPL(appl)->releasing--; - if (APPL(appl)->releasing <= 0) { + if (atomic_dec_and_test(&APPL(appl)->releasing)) { APPL(appl)->signal = 0; APPL_MARK_FREE(appl); printk(KERN_INFO "kcapi: appl %d down\n", appl); @@ -793,6 +792,12 @@ kfree_skb(skb); continue; } + if (atomic_read(&APPL(appl)->releasing)) { + printk(KERN_ERR "kcapi: recv_handler: applid %d is releasing\n", + appl); + kfree_skb(skb); + continue; + } if (APPL(appl)->signal == 0) { printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n", appl); @@ -869,7 +874,7 @@ for (appl = 1; appl <= CAPI_MAXAPPL; appl++) { if (!VALID_APPLID(appl)) continue; - if (APPL(appl)->releasing) continue; + if (atomic_read(&APPL(appl)->releasing)) continue; card->driver->register_appl(card, appl, &APPL(appl)->rparam); } @@ -1117,6 +1122,7 @@ APPL_MARK_USED(appl); skb_queue_head_init(&APPL(appl)->recv_queue); APPL(appl)->nncci = 0; + atomic_set(&APPL(appl)->releasing,0); memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params)); @@ -1136,19 +1142,18 @@ { int i; - if (!VALID_APPLID(applid) || APPL(applid)->releasing) + if (!VALID_APPLID(applid) || atomic_read(&APPL(applid)->releasing)) return CAPI_ILLAPPNR; - APPL(applid)->releasing++; + atomic_inc(&APPL(applid)->releasing); skb_queue_purge(&APPL(applid)->recv_queue); for (i = 0; i < CAPI_MAXCONTR; i++) { if (cards[i].cardstate != CARD_RUNNING) continue; - APPL(applid)->releasing++; + atomic_inc(&APPL(applid)->releasing); cards[i].driver->release_appl(&cards[i], applid); } - APPL(applid)->releasing--; - if (APPL(applid)->releasing <= 0) { - APPL(applid)->signal = 0; + if (atomic_dec_and_test(&APPL(applid)->releasing)) { + APPL(applid)->signal = 0; APPL_MARK_FREE(applid); printk(KERN_INFO "kcapi: appl %d down\n", applid); }