From 839b5172e6bb6c2dcb0ba0eb5ae6ae631af746ff Mon Sep 17 00:00:00 2001 From: markster Date: Fri, 6 Feb 2004 21:13:14 +0000 Subject: Clear pseudos at end of interrupt handler ONLY git-svn-id: http://svn.digium.com/svn/zaptel/trunk@308 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- zaptel.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'zaptel.c') diff --git a/zaptel.c b/zaptel.c index e6380d4..a2206c7 100755 --- a/zaptel.c +++ b/zaptel.c @@ -296,6 +296,10 @@ static struct zt_timer { static spinlock_t zaptimerlock = SPIN_LOCK_UNLOCKED; +static spinlock_t zapfreelock = SPIN_LOCK_UNLOCKED; + +static int zapneedfree = 0; + struct zt_zone { char name[40]; /* Informational, only */ int ringcadence[ZT_MAX_CADENCE]; @@ -1458,6 +1462,17 @@ static struct ppp_channel_ops ztppp_ops = }; #endif + +static void __zt_recalc_maxchans(void) +{ + int x; + maxchans = 0; + for (x=1;xflags & ZT_FLAG_OPEN) res = -EBUSY; + else if (chans[unit]->flags & ZT_FLAG_DEAD) + res = -EBUSY; else if (chans[unit]->flags & ZT_FLAG_NETDEV) res = -EBUSY; else if (chans[unit]->master != chans[unit]) @@ -2131,7 +2148,7 @@ static struct zt_chan *zt_alloc_pseudo(void) return pseudo; } -static void zt_free_pseudo(struct zt_chan *pseudo) +static void __zt_free_pseudo(struct zt_chan *pseudo) { if (pseudo) { zt_chan_unreg(pseudo); @@ -2139,6 +2156,18 @@ static void zt_free_pseudo(struct zt_chan *pseudo) } } +static void zt_free_pseudo(struct zt_chan *pseudo) +{ + long flags; + if (pseudo) { + /* Mark as dead for later reaping */ + pseudo->flags |= ZT_FLAG_DEAD; + spin_lock_irqsave(&zapfreelock, flags); + zapneedfree = 1; + spin_unlock_irqrestore(&zapfreelock, flags); + } +} + static int zt_open(struct inode *inode, struct file *file) { int unit = UNIT(file); @@ -5845,6 +5874,18 @@ int zt_receive(struct zt_span *span) spin_unlock_irqrestore(&chans[x]->lock, flags); } } + spin_lock_irqsave(&zapfreelock, flags); + if (zapneedfree) { + /* Free any pseudos that might need it */ + for (x=0;xflags & ZT_FLAG_DEAD)) { + __zt_free_pseudo(chans[x]); + } + } + } + __zt_recalc_maxchans(); + spin_unlock_irqrestore(&zapfreelock, flags); + } #endif return 0; -- cgit v1.2.3