/[hurd]/hurd/console/display.c
ViewVC logotype

Diff of /hurd/console/display.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.26 by marcus, Wed Sep 18 17:31:54 2002 UTC revision 1.27 by marcus, Sun Sep 22 00:17:43 2002 UTC
# Line 143  typedef struct attr *attr_t; Line 143  typedef struct attr *attr_t;
143    
144  struct user_pager_info  struct user_pager_info
145  {  {
   display_t display;  
   struct pager *p;  
146    size_t memobj_npages;    size_t memobj_npages;
147    vm_address_t memobj_pages[0];    vm_address_t memobj_pages[0];
148  };  };
# Line 195  struct display Line 193  struct display
193    
194    struct cons_display *user;    struct cons_display *user;
195    
196    struct user_pager_info *upi;      struct pager *pager;  
197    memory_object_t memobj;    memory_object_t memobj;
198    
199    /* A list of ports to send file change notifications to.  */    /* A list of ports to send file change notifications to.  */
# Line 276  pager_report_extent (struct user_pager_i Line 274  pager_report_extent (struct user_pager_i
274                       vm_address_t *offset,                       vm_address_t *offset,
275                       vm_size_t *size)                       vm_size_t *size)
276  {  {
   display_t display = upi->display;  
277    *offset = 0;    *offset = 0;
278    *size = display->upi->memobj_npages * vm_page_size;    *size =  upi->memobj_npages * vm_page_size;
279    return 0;    return 0;
280  }  }
281    
# Line 405  free_modreqs (struct modreq *mr) Line 402  free_modreqs (struct modreq *mr)
402    struct modreq *tmp;    struct modreq *tmp;
403    for (; mr; mr = tmp)    for (; mr; mr = tmp)
404      {      {
405          mach_port_t old;
406          /* Cancel the dead-name notification.  */
407          mach_port_request_notification (mach_task_self (), mr->port,
408                                          MACH_NOTIFY_DEAD_NAME, 0,
409                                          MACH_PORT_NULL,
410                                          MACH_MSG_TYPE_MAKE_SEND_ONCE, &old);
411          mach_port_deallocate (mach_task_self (), old);
412    
413          /* Deallocate the user's port.  */
414        mach_port_deallocate (mach_task_self (), mr->port);        mach_port_deallocate (mach_task_self (), mr->port);
415        tmp = mr->next;        tmp = mr->next;
416        free (mr);        free (mr);
417      }      }
418  }  }
419    
420  void do_mach_notify_port_deleted (void) { assert (0); }  /* A port deleted notification is generated when we deallocate the
421       user's notify port before it is dead.  */
422    error_t
423    do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
424    {
425      /* As we cancel the dead-name notification before deallocating the
426         port, this should not happen.  */
427      assert (0);
428    }
429    
430    /* We request dead name notifications for the user ports.  */
431    error_t
432    do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_name)
433    {
434      struct notify *notify_port = ports_lookup_port (notify_bucket,
435                                                      notify, notify_class);
436      struct display *display;
437      struct modreq **preq;
438      struct modreq *req;
439    
440      if (!notify_port)
441        return EOPNOTSUPP;
442    
443      display = notify_port->display;
444      mutex_lock (&display->lock);
445      
446      /* Find request in pending queue.  */
447      preq = &display->filemod_reqs_pending;
448      while (*preq && (*preq)->port != dead_name)
449        preq = &(*preq)->next;
450      if (! *preq)
451        {
452          /* Find request in queue.  */
453          preq = &display->filemod_reqs;
454          while (*preq && (*preq)->port != dead_name)
455            preq = &(*preq)->next;
456        }
457    
458      if (*preq)
459        {
460          req = *preq;
461          *preq = req->next;
462    
463          mach_port_deallocate (mach_task_self (), req->port);
464          free (req);
465        }
466      mutex_unlock (&display->lock);
467      
468      /* Drop gratuitous extra reference that the notification creates. */
469      mach_port_deallocate (mach_task_self (), dead_name);
470      
471      return 0;
472    }
473    
474  void do_mach_notify_port_destroyed (void) { assert (0); }  void do_mach_notify_port_destroyed (void) { assert (0); }
475  void do_mach_notify_no_senders (void) { assert (0); }  
476  void do_mach_notify_dead_name (void) { assert (0); }  error_t
477    do_mach_notify_no_senders (mach_port_t port, mach_port_mscount_t count)
478    {
479      return ports_do_mach_notify_no_senders (port, count);
480    }
481    
482  kern_return_t  kern_return_t
483  do_mach_notify_send_once (mach_port_t notify)  do_mach_notify_send_once (mach_port_t notify)
484  {  {
485    /* XXX Not sure when this is called.  */    return 0;
   assert (0);  
486  }  }
487    
488  kern_return_t  kern_return_t
# Line 473  do_mach_notify_msg_accepted (mach_port_t Line 535  do_mach_notify_msg_accepted (mach_port_t
535                                   notify);                                   notify);
536        if (err && err != MACH_SEND_WILL_NOTIFY)        if (err && err != MACH_SEND_WILL_NOTIFY)
537          {          {
538              mach_port_t old;
539            *preq = req->next;            *preq = req->next;
540            mutex_unlock (&display->lock);            mutex_unlock (&display->lock);
541    
542              /* Cancel the dead-name notification.  */
543              mach_port_request_notification (mach_task_self (), req->port,
544                                              MACH_NOTIFY_DEAD_NAME, 0,
545                                              MACH_PORT_NULL,
546                                              MACH_MSG_TYPE_MAKE_SEND_ONCE, &old);
547              mach_port_deallocate (mach_task_self (), old);
548    
549            mach_port_deallocate (mach_task_self (), req->port);            mach_port_deallocate (mach_task_self (), req->port);
550            free (req);            free (req);
551            ports_port_deref (notify_port);            ports_port_deref (notify_port);
# Line 516  display_notice_changes (display_t displa Line 587  display_notice_changes (display_t displa
587  {  {
588    error_t err;    error_t err;
589    struct modreq *req;    struct modreq *req;
590      mach_port_t notify_port;
591      mach_port_t old;
592    
593    mutex_lock (&display->lock);    mutex_lock (&display->lock);
594    err = nowait_file_changed (notify, 0, FILE_CHANGED_NULL, 0, 0, MACH_PORT_NULL);    err = nowait_file_changed (notify, 0, FILE_CHANGED_NULL, 0, 0,
595                                 MACH_PORT_NULL);
596    if (err)    if (err)
597      {      {
598        mutex_unlock (&display->lock);        mutex_unlock (&display->lock);
599        return err;        return err;
600      }      }
601    
602    req = malloc (sizeof (struct modreq));    req = malloc (sizeof (struct modreq));
603    if (!req)    if (!req)
604      {      {
605        mutex_unlock (&display->lock);        mutex_unlock (&display->lock);
606        return errno;        return errno;
607      }      }
608    
609      notify_port = ports_get_right (display->notify_port);
610    
611      /* Request dead-name notification for the user's port.  */
612      err = mach_port_request_notification (mach_task_self (), notify,
613                                            MACH_NOTIFY_DEAD_NAME, 0,
614                                            notify_port,
615                                            MACH_MSG_TYPE_MAKE_SEND_ONCE, &old);
616      if (err)
617        {
618          free (req);
619          mutex_unlock (&display->lock);
620          return err;
621        }
622      assert (old == MACH_PORT_NULL);
623    
624    req->port = notify;    req->port = notify;
625    req->pending = 0;    req->pending = 0;
626    req->next = display->filemod_reqs;    req->next = display->filemod_reqs;
# Line 571  display_notice_filechange (display_t dis Line 662  display_notice_filechange (display_t dis
662              }              }
663            else            else
664              {              {
665                  mach_port_t old;
666    
667                  /* Cancel the dead-name notification.  */
668                  mach_port_request_notification (mach_task_self (), req->port,
669                                                  MACH_NOTIFY_DEAD_NAME, 0,
670                                                  MACH_PORT_NULL, 0, &old);
671                  mach_port_deallocate (mach_task_self (), old);
672                mach_port_deallocate (mach_task_self (), req->port);                mach_port_deallocate (mach_task_self (), req->port);
673                free (req);                free (req);
674              }              }
# Line 782  user_create (display_t display, uint32_t Line 880  user_create (display_t display, uint32_t
880  {  {
881    error_t err;    error_t err;
882    struct cons_display *user;    struct cons_display *user;
883      struct user_pager_info *upi;
884    
885    int npages = (round_page (sizeof (struct cons_display) +    int npages = (round_page (sizeof (struct cons_display) +
886                             sizeof (conchar_t) * width * lines)) / vm_page_size;                             sizeof (conchar_t) * width * lines)) / vm_page_size;
887    
888    display->upi = calloc (1, sizeof (struct user_pager_info)    upi = calloc (1, sizeof (struct user_pager_info)
889                           + sizeof (vm_address_t) * npages);                  + sizeof (vm_address_t) * npages);
890    if (!display->upi)    if (!upi)
891      return MACH_PORT_NULL;      return MACH_PORT_NULL;
892    display->upi->display = display;    upi->memobj_npages = npages;
   display->upi->memobj_npages = npages;  
893    /* 1 & MOCD correct? */    /* 1 & MOCD correct? */
894    display->upi->p = pager_create (display->upi, pager_bucket,    display->pager = pager_create (upi, pager_bucket,
895                                    1, MEMORY_OBJECT_COPY_DELAY);                                   1, MEMORY_OBJECT_COPY_DELAY);
896    if (display->upi->p == 0)    if (display->pager == 0)
897      {      {
898        free (display->upi);        free (upi);
899        return errno;        return errno;
900      }      }
901    display->memobj = pager_get_port (display->upi->p);    display->memobj = pager_get_port (display->pager);
902    ports_port_deref (display->upi->p);    ports_port_deref (display->pager);
903    
904    mach_port_insert_right (mach_task_self (), display->memobj, display->memobj,    mach_port_insert_right (mach_task_self (), display->memobj, display->memobj,
905                            MACH_MSG_TYPE_MAKE_SEND);                            MACH_MSG_TYPE_MAKE_SEND);
906    
907    err = vm_map (mach_task_self (),    err = vm_map (mach_task_self (),
908                  (vm_address_t *) &user,                  (vm_address_t *) &user,
909                  (vm_size_t) display->upi->memobj_npages * vm_page_size,                  (vm_size_t) npages * vm_page_size,
910                  (vm_address_t) 0,                  (vm_address_t) 0,
911                  1 /* ! (flags & MAP_FIXED) */,                  1 /* ! (flags & MAP_FIXED) */,
912                  display->memobj, 0 /* (vm_offset_t) offset */,                  display->memobj, 0 /* (vm_offset_t) offset */,
# Line 816  user_create (display_t display, uint32_t Line 914  user_create (display_t display, uint32_t
914                  VM_PROT_READ | VM_PROT_WRITE,                  VM_PROT_READ | VM_PROT_WRITE,
915                  VM_PROT_READ | VM_PROT_WRITE,                  VM_PROT_READ | VM_PROT_WRITE,
916                  VM_INHERIT_NONE);                  VM_INHERIT_NONE);
917    
918    if (err)    if (err)
919      {      {
920        /* UPI will be cleaned up by libpager.  */        /* UPI will be cleaned up by libpager.  */
# Line 848  static void Line 947  static void
947  user_destroy (display_t display)  user_destroy (display_t display)
948  {  {
949    /* The pager will be deallocated by libpager.  */    /* The pager will be deallocated by libpager.  */
950      vm_deallocate (mach_task_self (), (vm_offset_t) display->user,
951                     pager_get_upi (display->pager)->memobj_npages * vm_page_size);
952    mach_port_deallocate (mach_task_self (), display->memobj);    mach_port_deallocate (mach_task_self (), display->memobj);
953  }  }
954    
# Line 1899  display_create (display_t *r_display, co Line 2000  display_create (display_t *r_display, co
2000  void  void
2001  display_destroy (display_t display)  display_destroy (display_t display)
2002  {  {
2003      mutex_lock (&display->lock);
2004    if (display->filemod_reqs_pending)    if (display->filemod_reqs_pending)
2005      free_modreqs (display->filemod_reqs_pending);      {
2006          free_modreqs (display->filemod_reqs_pending);
2007          display->filemod_reqs_pending = NULL;
2008        }
2009    if (display->filemod_reqs)    if (display->filemod_reqs)
2010      free_modreqs (display->filemod_reqs);      {
2011          free_modreqs (display->filemod_reqs);
2012          display->filemod_reqs = NULL;
2013        }
2014    ports_destroy_right (display->notify_port);    ports_destroy_right (display->notify_port);
2015    output_deinit (&display->output);    output_deinit (&display->output);
2016    user_destroy (display);    user_destroy (display);
2017      mutex_unlock (&display->lock);
2018    
2019    /* We can not free the display structure here, because it might    /* We can not free the display structure here, because it might
2020       still be needed by pending modification requests when msg       still be needed by pending modification requests when msg
2021       accepted notifications are handled.  So we have to wait until all       accepted notifications are handled.  So we have to wait until all

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26