egcs-1.1b hangs (never returns)

Carlo Wood carlo@runaway.xs4all.nl
Thu Oct 15 17:26:00 GMT 1998


The following code makes egcs-1.1b never return, ie

  PID  PPID USER     TTY  NI  SIZE SWAP  RSS SHARE WCHAN    STAT %CPU %MEM CO
13426 13424 carlo     p3   0 15152    0  14M  1528 0        R    96.1 24.1 cc1

for ever...

Compile with:

>g++ -v -c events2.cc
Reading specs from /usr/local/egcs/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.91.57/specs
gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
 /usr/local/egcs/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.91.57/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__GNUC_MINOR__=91 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__EXCEPTIONS -Asystem(unix) -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__ events2.cc /tmp/ccIcU1uV.ii
GNU CPP version egcs-2.91.57 19980901 (egcs-1.1 release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/egcs/include/g++
 /usr/local/include
 /usr/local/egcs/i686-pc-linux-gnu/include
 /usr/local/egcs/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.91.57/include
 /usr/include
End of search list.
 /usr/local/egcs/lib/gcc-lib/i686-pc-linux-gnu/egcs-2.91.57/cc1plus /tmp/ccIcU1uV.ii -quiet -dumpbase events2.cc -version -o /tmp/ccSEvBJQ.s
GNU C++ version egcs-2.91.57 19980901 (egcs-1.1 release) (i686-pc-linux-gnu) compiled by GNU C version egcs-2.91.57 19980901 (egcs-1.1 release).
... (hangs here)

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

File "events2.cc":
--------------------
//
// Author:
//
// 1024/624ACAD5 1997/01/26 Carlo Wood, Run on IRC <carlo@runaway.xs4all.nl>
// Key fingerprint = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
// Get key from pgp-public-keys server or
// finger carlo@runaway.xs4all.nl for public key (dialin, try at 21-22h GMT).
//

#include <list>

class event_data_ct {
public:
  virtual bool check_range(void) = 0;
};

template<class EVENTTYPE>
class event_server_tct {
public:
  typedef typename EVENTTYPE::event_data_ct event_data_ct;
  typedef EVENTTYPE event_type_ct;
private:
#ifdef DEBUG
  void __type_check(void) { event_data_ct *ed __attribute__((unused)) = (event_type_ct *)NULL; }
      // Check that event_data_ct is base class of event_type_ct
#endif
};

template<class EVENTTYPE>
class event_request_btct {
private:
  unsigned int reference_count;

protected:
  virtual ~event_request_btct()
      {
#ifdef DEBUG
	if (reference_count)
	  cdeb_fatal << "Deleting an event_request_btct with reference_count != 0" << endl_fatal;
#endif
      }

public:
  event_request_btct(void) : reference_count(1) {}
  virtual void triggered(const typename EVENTTYPE::event_data_ct &eventdata) = 0;
  void add_reference(void) { ++reference_count; }
  void release(void) { if (!--reference_count) delete this; }
};

class event_ct {
};

template<class EVENTTYPE>
class event_tct : public event_ct {
  event_request_btct<EVENTTYPE> *event_request;
  const EVENTTYPE &event_type;
public:
  event_tct(event_request_btct<EVENTTYPE> *er, const EVENTTYPE &et) : event_request(er), event_type(et) { }
};

class never_busy_interface_ct {
public:
  bool is_busy(void) { return false; }
  void set_busy(void) { }
  void unset_busy(void) { }
  void store(void *) { }
};

class busy_interface_ct {
private:
  bool busy;
  list<event_request_btct<event_ct> *> events;

public:
  static never_busy_interface_ct none;		// Hook for empty busy interface

  busy_interface_ct(void) : busy(false) { }

  bool is_busy(void) { return busy; }
  void set_busy(void) { busy = true; }
  void unset_busy(void) { busy = false; }
  template<class EVENTTYPE>
  void store(event_request_btct<EVENTTYPE> *event_request, const EVENTTYPE &et)
      { events.push_back(new event_tct<EVENTTYPE>(event_request, et)); }
};

//-----------------------------------------------------------------------------
//
// Simple Event Server template
//
// This event server simply stores are all requests in one list
// and subsequently calls the methods of the event clients when
// the event is triggered (by calling the method `trigger()').
//
// This simple event server does not allow you to pass data with the
// request and handles the events in the same order as they are arrived
// (No priorities).
//

template<class EVENTTYPE>
class simple_event_server_tct : public event_server_tct<EVENTTYPE> {
public:
  template<class EVENTCLIENT, class BUSYINTERFACE>
  class event_request_tct : public event_request_btct<EVENTTYPE> {
    EVENTCLIENT event_client;
    void (EVENTCLIENT::*callbackfunc)(const event_type_ct &);
    BUSYINTERFACE busy_interface;
  public:
    event_request_tct(EVENTCLIENT ec, void (EVENTCLIENT::*em)(const event_type_ct &), BUSYINTERFACE bi)
        : event_client(ec), callbackfunc(em), busy_interface(bi) { }
    virtual void triggered(const typename EVENTTYPE::event_data_ct &d);
  };

private:
  typedef list<event_request_btct<EVENTTYPE> *> request_list_ct;
  request_list_ct clients;

public:
  ~simple_event_server_tct();
  template<class EVENTCLIENT, class BUSYINTERFACE>
  void request(EVENTCLIENT *ec, void (EVENTCLIENT::*em)(const event_type_ct &), BUSYINTERFACE bi);
  void trigger(const typename EVENTTYPE::event_data_ct &d);
};

template<class EVENTTYPE>
simple_event_server_tct<EVENTTYPE>::~simple_event_server_tct()
{
  for (request_list_ct::iterator i = clients.begin(); i != clients.end(); ++i)
    (*i)->release();
}

template<class EVENTTYPE>
template<class EVENTCLIENT, class BUSYINTERFACE>
void simple_event_server_tct<EVENTTYPE>::request(EVENTCLIENT *ec, void (EVENTCLIENT::*em)(const event_type_ct &), BUSYINTERFACE bi)
{
  clients.push_back(new event_request_tct<EVENTCLIENT, BUSYINTERFACE>(ec, em, bi));
}

template<class EVENTTYPE>
template<class EVENTCLIENT, class BUSYINTERFACE>
void simple_event_server_tct<EVENTTYPE>::event_request_tct::triggered(const typename EVENTTYPE::event_data_ct &d)
{
  if (bi.is_busy())
  {
    bi.store(this, d);
    add_reference();
  }
  else
  {
    bi.set_busy();
    (ptr.*func)(d);
    bi.unset_busy();
  }
}

template<class EVENTTYPE>
void simple_event_server_tct<EVENTTYPE>::trigger(const typename EVENTTYPE::event_data_ct &d)
{
  for (request_list_ct::iterator i = clients.begin(); i != clients.end(); ++i)
    (*i)->triggered(d);
}

never_busy_interface_ct busy_interface_ct::none;




More information about the Gcc-bugs mailing list