Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: reading two elementary PIDs (Aud and Vid) at once



On Thursday 31 October 2002 04:07 pm, Mike Doyle wrote:
> Does this mean I should be trying another way of getting two Elementary
> streams (any suggestions)?
>
> If not, is there a fix? Or work around?
>
> thanks again
> Mike

When trying to do the same thing, I found in the "old" driver that when 
DmxDevRead was called it locked the underlying dmxdev mutex so that all other 
reads were blocked.  A second process would grab the lock and starve the 
first process because of the race condition set up with two processes trying 
to read the demux device.  The way we got around it was to add a filter 
specific mutex and to use this mutex when DmxDevRead was called, instead of 
locking the dmxdev mutex.  This allowed multiple filters to be read at one 
time, thereby fixing the problem.  We are in the process of converting to the 
new drivers so I do not yet know if the same problem exists there...	

Here is the patch to the old driver if it is of any use...  hope this helps.


[mdavis cvs]$ diff -ru DVB/ temp/DVB/
diff -ru DVB/driver/dmxdev.c temp/DVB/driver/dmxdev.c
--- DVB/driver/dmxdev.c Thu Aug  1 11:46:11 2002
+++ temp/DVB/driver/dmxdev.c    Thu Aug 15 12:49:57 2002
@@ -722,6 +726,7 @@
                 return -EMFILE;
        }
         dmxdevfilter=&dmxdev->filter[i];
+       sema_init(&dmxdevfilter->mutex, 1);
        file->private_data=dmxdevfilter;
 
        DmxDevBufferInit(&dmxdevfilter->buffer);
@@ -747,6 +752,11 @@
                up(&dmxdev->mutex);
                return -EINVAL;
         }
+       
+       if (down_interruptible(&dmxdevfilter->mutex)) {
+               up(&dmxdev->mutex);
+               return -ERESTARTSYS;
+       }
 
         DmxDevFilterStop(dmxdevfilter);
        DmxDevFilterReset(dmxdevfilter);
@@ -761,6 +771,7 @@
        }
        DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_FREE);
        wake_up(&dmxdevfilter->buffer.queue);
+       up(&dmxdevfilter->mutex);
        up(&dmxdev->mutex);
        //printk("free filters = %d\n", DmxDevFilterNum(dmxdev));
         return 0;
@@ -907,7 +924,7 @@
         dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file);
        int ret=0;
 
-        if (down_interruptible(&dmxdev->mutex))
+        if (down_interruptible(&dmxdevfilter->mutex))
                return -ERESTARTSYS;
 
        if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
@@ -916,7 +933,7 @@
                ret=DmxDevBufferRead(&dmxdevfilter->buffer, 
                                     file->f_flags&O_NONBLOCK, 
                                     buf, count, ppos);
-        up(&dmxdev->mutex);
+        up(&dmxdevfilter->mutex);
        return ret;
 }
 
@@ -937,14 +954,26 @@
 
        switch (cmd) {
        case DMX_START: 
+               if (down_interruptible(&dmxdevfilter->mutex)) {
+                     up(&dmxdev->mutex);
+                     return -ERESTARTSYS;
+               }
+
                if (dmxdevfilter->state<DMXDEV_STATE_SET)
                        ret=-EINVAL;
                else
                        ret=DmxDevFilterStart(dmxdevfilter);
+
+               up(&dmxdevfilter->mutex);
                break;
 
        case DMX_STOP: 
+               if (down_interruptible(&dmxdevfilter->mutex)) {
+                     up(&dmxdev->mutex);
+                     return -ERESTARTSYS;
+               }
                ret=DmxDevFilterStop(dmxdevfilter);
+               up(&dmxdevfilter->mutex);
                break;
 
        case DMX_SET_FILTER: 
@@ -954,8 +983,14 @@
                if (copy_from_user(&params, parg, sizeof(params)))
                        
                        ret=-EFAULT;
-               else
+               else {
+                       if (down_interruptible(&dmxdevfilter->mutex)) {
+                               up(&dmxdev->mutex);
+                               return -ERESTARTSYS;
+                       }
                        ret=DmxDevFilterSet(dmxdev, dmxdevfilter, &params);
+                       up(&dmxdevfilter->mutex);
+               }
                break;
        }
 
@@ -965,13 +1000,24 @@
                
                if (copy_from_user(&params, parg, sizeof(params)))
                        ret=-EFAULT;
-               else
+               else {
+                       if (down_interruptible(&dmxdevfilter->mutex)) {
+                             up(&dmxdev->mutex);
+                             return -ERESTARTSYS;
+                       }
                        ret=DmxDevPesFilterSet(dmxdev, dmxdevfilter, &params);
+                       up(&dmxdevfilter->mutex);
+               }
                break;
        }
 
        case DMX_SET_BUFFER_SIZE: 
+               if (down_interruptible(&dmxdevfilter->mutex)) {
+                     up(&dmxdev->mutex);
+                     return -ERESTARTSYS;
+               }
                ret=DmxDevSetBufferSize(dmxdevfilter, arg);
+               up(&dmxdevfilter->mutex);
                break;
         
         case DMX_GET_EVENT: 
diff -ru DVB/driver/dmxdev.h temp/DVB/driver/dmxdev.h
--- DVB/driver/dmxdev.h Mon Oct 29 05:51:26 2001
+++ temp/DVB/driver/dmxdev.h    Wed Aug  7 15:08:30 2002
@@ -96,6 +96,8 @@
         struct dmxdev_s *dev;
         dmxdev_buffer_t buffer;
 
+        struct semaphore mutex;
+
         // only for sections
         struct timer_list timer;
         int todo;





--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index