aboutsummaryrefslogtreecommitdiff
path: root/iemnet_notify.c
blob: df1c9ebc9f0b378eb46933e788eb33f53f982fd1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* iemnet
 *
 * notify
 *   notifies mai thread that new data has arrived
 *
 *  copyright (c) 2012 IOhannes m zmölnig, IEM
 */

/* This program is free software; you can redistribute it and/or                */
/* modify it under the terms of the GNU General Public License                  */
/* as published by the Free Software Foundation; either version 2               */
/* of the License, or (at your option) any later version.                       */
/*                                                                              */
/* This program is distributed in the hope that it will be useful,              */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of               */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                */
/* GNU General Public License for more details.                                 */
/*                                                                              */
/* You should have received a copy of the GNU General Public License            */
/* along with this program; if not, write to the Free Software                  */
/* Foundation, Inc.,                                                            */
/* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                  */
/*                                                                              */

#define DEBUGLEVEL 4

#include "iemnet.h"
#include "iemnet_data.h"

/* for pipe() */
#include <unistd.h>

/* for printf() debugging */
#include <stdio.h>

typedef struct _iemnet_notify{
  void*data;
  t_iemnet_notifun fun;
  struct _iemnet_notifier*parent;
  struct _iemnet_notify*next;
} t_iemnet_notify;

static t_iemnet_notify*pollqueue=NULL;

typedef struct _iemnet_notifier {
  int fd[2];
  struct _iemnet_notify*nodes;
} t_iemnet_notifier;

static t_iemnet_notifier *masternotifier = NULL;

/* notifies Pd that there is new data to fetch */
void iemnet__notify(t_iemnet_notify*x) {
  write(masternotifier->fd[1], x, sizeof(x));
}

static void pollfun(void*x, int fd) {
  char buf[4096];
  int result=-1;
  t_iemnet_notify*q;
  result=read(fd, buf, sizeof(buf));
  for(q=pollqueue; q; q=q->next) {
    (q->fun)(q->data);
  }
}

static void iemnet__notifier_print(t_iemnet_notifier*x) {
  t_iemnet_notify*q;
  for(q=pollqueue; q; q=q->next) {
    printf("queue[%p]={fun:%p, data:%p, next:%p}\n", q, q->fun, q->data, q->next);
  }
}
t_iemnet_notifier*iemnet__notify_create(void) {
  if(masternotifier!=NULL)
    return masternotifier;
  masternotifier=(t_iemnet_notifier*)getbytes(sizeof(t_iemnet_notifier));
  if(!pipe(masternotifier->fd)) {
    sys_addpollfn(masternotifier->fd[0], pollfun, masternotifier);
    return masternotifier;
  }
  return NULL;
}
void iemnet__notify_destroy(t_iemnet_notifier*x) {
  // nada
}

t_iemnet_notify*iemnet__notify_add(t_iemnet_notifier*notifier, t_iemnet_notifun fun, void*data) {
  /* add the given receiver to the poll-queue
   * LATER: check whether it's already in there...
   */
  t_iemnet_notify*q=(t_iemnet_notify*)getbytes(sizeof(t_iemnet_notify));
  q->fun =fun;
  q->data=data;
  q->parent=notifier;
  q->next=pollqueue;
  pollqueue=q;
  //iemnet__notifier_print(notifier);
  return q;
}
void iemnet__notify_remove(t_iemnet_notify*x) {
  t_iemnet_notify*q=pollqueue;
  t_iemnet_notify*last=NULL;
  //iemnet__notifier_print(q->parent);

  for(q=pollqueue; q; q=q->next) {
    if(q == x) {
      if(last) {
        last->next=q->next;
      } else {
        pollqueue=q->next;
      }
      q->fun =NULL;
      q->data=NULL;
      q->next=NULL;
      freebytes(q, sizeof(*q));
      return;
    }
    last=q;
  }
}