~kamalmostafa/ubuntu/lucid/pdp/fix-504941-ftbfs

« back to all changes in this revision

Viewing changes to modules/generic/pdp_rawin.c

  • Committer: Bazaar Package Importer
  • Author(s): Guenter Geiger (Debian/GNU)
  • Date: 2005-03-15 22:21:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050315222105-1q287rsihmd9j1tb
Tags: 1:0.12.4-2
* fixed the hardcoded depends
* added 3dp library

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *   Pure Data Packet module. packet forth console
3
 
 *   Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
4
 
 *
5
 
 *   This program is free software; you can redistribute it and/or modify
6
 
 *   it under the terms of the GNU General Public License as published by
7
 
 *   the Free Software Foundation; either version 2 of the License, or
8
 
 *   (at your option) any later version.
9
 
 *
10
 
 *   This program is distributed in the hope that it will be useful,
11
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *   GNU General Public License for more details.
14
 
 *
15
 
 *   You should have received a copy of the GNU General Public License
16
 
 *   along with this program; if not, write to the Free Software
17
 
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
 *
19
 
 */
20
 
 
21
 
 
22
 
#include <pthread.h>
23
 
#include <stdio.h>
24
 
#include <unistd.h>
25
 
#include <stdlib.h>
26
 
#include <sys/types.h>
27
 
#include <sys/stat.h>
28
 
#include <sys/time.h>
29
 
#include <time.h>
30
 
#include <fcntl.h>
31
 
#include "pdp_pd.h"
32
 
#include "pdp_debug.h"
33
 
#include "pdp_list.h"
34
 
#include "pdp_comm.h"
35
 
#include "pdp_post.h"
36
 
#include "pdp_packet.h"
37
 
 
38
 
 
39
 
#define PERIOD 1.0f
40
 
#define D if (1)
41
 
 
42
 
 
43
 
 
44
 
 
45
 
/* raw input from a unix pipe */
46
 
 
47
 
typedef struct rawin_struct
48
 
{
49
 
    /* pd */
50
 
    t_object x_obj;
51
 
    t_outlet *x_outlet;
52
 
    t_outlet *x_sync_outlet;
53
 
    t_clock *x_clock;
54
 
 
55
 
    /* comm */
56
 
    t_pdp_list *x_queue; // packet queue
57
 
 
58
 
    /* thread */
59
 
    pthread_mutex_t x_mut;
60
 
    pthread_attr_t x_attr;
61
 
    pthread_t x_thread;
62
 
 
63
 
    /* sync */
64
 
    int x_giveup;  // 1-> terminate reader thread
65
 
    int x_active;  // 1-> reader thread is launched
66
 
    int x_done;    // 1-> reader thread has exited
67
 
 
68
 
    /* config */
69
 
    t_symbol *x_pipe;
70
 
    t_pdp_symbol *x_type;
71
 
 
72
 
} t_rawin;
73
 
 
74
 
 
75
 
static inline void lock(t_rawin *x){pthread_mutex_lock(&x->x_mut);}
76
 
static inline void unlock(t_rawin *x){pthread_mutex_unlock(&x->x_mut);}
77
 
 
78
 
static void rawin_close(t_rawin *x);
79
 
static void tick(t_rawin *x)
80
 
{
81
 
    /* send all packets in queue to outlet */
82
 
    lock(x);
83
 
    while (x->x_queue->elements){
84
 
        outlet_pdp_atom(x->x_outlet, x->x_queue->first);
85
 
        pdp_list_pop(x->x_queue); // pop stale reference
86
 
    }
87
 
    unlock(x);
88
 
    clock_delay(x->x_clock, PERIOD);
89
 
 
90
 
    /* check if thread is done */
91
 
    if (x->x_done) rawin_close(x);
92
 
 
93
 
}
94
 
 
95
 
static void move_current_to_queue(t_rawin *x, int packet)
96
 
{
97
 
    lock(x);
98
 
    pdp_list_add_back(x->x_queue, a_packet, (t_pdp_word)packet);
99
 
    unlock(x);
100
 
}
101
 
 
102
 
static void *rawin_thread(void *y)
103
 
{
104
 
    int pipe;
105
 
    int packet = -1;
106
 
    t_rawin *x = (t_rawin *)y;
107
 
    int period_sec;
108
 
    int period_usec;
109
 
 
110
 
 
111
 
    //D pdp_post("pipe: %s", x->x_pipe->s_name);
112
 
    //D pdp_post("type: %s", x->x_type->s_name);
113
 
 
114
 
    /* open pipe */
115
 
    if (-1 == (pipe = open(x->x_pipe->s_name, O_RDONLY|O_NONBLOCK))){
116
 
        perror(x->x_pipe->s_name);
117
 
        goto exit;
118
 
    }
119
 
 
120
 
    /* main loop (packets) */
121
 
    while(1){
122
 
        void *data = 0;
123
 
        int left = -1;
124
 
 
125
 
        /* create packet */
126
 
        if (-1 != packet){
127
 
            pdp_post("WARNING: deleting stale packet");
128
 
            pdp_packet_mark_unused(packet);
129
 
        }
130
 
        packet = pdp_factory_newpacket(x->x_type);
131
 
        if (-1 == packet){
132
 
            pdp_post("ERROR: can't create packet. type = %s", x->x_type->s_name);
133
 
            goto exit;
134
 
        }
135
 
        
136
 
        /* fill packet */
137
 
        data = pdp_packet_data(packet);
138
 
        left = pdp_packet_data_size(packet);
139
 
        // D pdp_post("packet %d, data %x, size %d", packet, data, left);
140
 
 
141
 
        /* inner loop: pipe reads */
142
 
        while(left){
143
 
 
144
 
            fd_set inset;
145
 
            struct timeval tv = {0,10000};
146
 
 
147
 
            /* check if we need to stop */
148
 
            if (x->x_giveup){
149
 
                pdp_packet_mark_unused(packet);
150
 
                goto close;
151
 
            }
152
 
            /* select, with timeout */
153
 
            FD_ZERO(&inset);
154
 
            FD_SET(pipe, &inset);
155
 
            if (-1 == select(pipe+1, &inset, NULL,NULL, &tv)){
156
 
                pdp_post("select error");
157
 
                goto close;
158
 
            }
159
 
 
160
 
            /* if ready, read, else retry */
161
 
            if (FD_ISSET(pipe, &inset)){
162
 
                int bytes = read(pipe, data, left);
163
 
                if (!bytes){
164
 
                    /* if no bytes are read, pipe is closed */
165
 
                    goto close;
166
 
                }
167
 
                data += bytes;
168
 
                left -= bytes;
169
 
            }
170
 
        }
171
 
                   
172
 
        /* move to queue */
173
 
        move_current_to_queue(x, packet);
174
 
        packet = -1;
175
 
 
176
 
 
177
 
    
178
 
    }
179
 
 
180
 
  close:
181
 
    /* close pipe */
182
 
    close(pipe);
183
 
        
184
 
        
185
 
  exit:
186
 
    x->x_done = 1;
187
 
    return 0;
188
 
}
189
 
 
190
 
 
191
 
 
192
 
static void rawin_type(t_rawin *x, t_symbol *type)
193
 
{
194
 
    x->x_type = pdp_gensym(type->s_name);
195
 
}
196
 
 
197
 
static void rawin_open(t_rawin *x, t_symbol *pipe)
198
 
{
199
 
    /* save pipe name if not empty */
200
 
    if (pipe->s_name[0]) {x->x_pipe = pipe;}
201
 
 
202
 
    if (x->x_active) {
203
 
        pdp_post("already open");
204
 
        return;
205
 
    }
206
 
    /* start thread */
207
 
    x->x_giveup = 0;
208
 
    x->x_done = 0;
209
 
    pthread_create(&x->x_thread, &x->x_attr, rawin_thread , x);
210
 
    x->x_active = 1;
211
 
}
212
 
 
213
 
static void rawin_close(t_rawin *x)
214
 
{
215
 
 
216
 
    if (!x->x_active) return;
217
 
 
218
 
    /* stop thread: set giveup + wait */
219
 
    x->x_giveup = 1;
220
 
    pthread_join(x->x_thread, NULL);
221
 
    x->x_active = 0;
222
 
 
223
 
    /* notify */
224
 
    outlet_bang(x->x_sync_outlet);
225
 
    pdp_post("connection to %s closed", x->x_pipe->s_name);
226
 
 
227
 
    
228
 
 
229
 
 
230
 
    
231
 
}
232
 
 
233
 
static void rawin_free(t_rawin *x)
234
 
{
235
 
    rawin_close(x);
236
 
    clock_free(x->x_clock);
237
 
    pdp_tree_strip_packets(x->x_queue);
238
 
    pdp_tree_free(x->x_queue);
239
 
}
240
 
 
241
 
t_class *rawin_class;
242
 
 
243
 
 
244
 
static void *rawin_new(t_symbol *pipe, t_symbol *type)
245
 
{
246
 
    t_rawin *x;
247
 
 
248
 
    pdp_post("%s %s", pipe->s_name, type->s_name);
249
 
 
250
 
    /* allocate & init */
251
 
    x = (t_rawin *)pd_new(rawin_class);
252
 
    x->x_outlet = outlet_new(&x->x_obj, &s_anything);
253
 
    x->x_sync_outlet = outlet_new(&x->x_obj, &s_anything);
254
 
    x->x_clock = clock_new(x, (t_method)tick);
255
 
    x->x_queue = pdp_list_new(0);
256
 
    x->x_active = 0;
257
 
    x->x_giveup = 0;
258
 
    x->x_done = 0;
259
 
    x->x_type = pdp_gensym("image/YCrCb/320x240"); //default
260
 
    x->x_pipe = gensym("/tmp/pdpraw"); // default
261
 
    pthread_attr_init(&x->x_attr);
262
 
    pthread_mutex_init(&x->x_mut, NULL);
263
 
    clock_delay(x->x_clock, PERIOD);
264
 
 
265
 
    /* args */
266
 
    rawin_type(x, type);
267
 
    if (pipe->s_name[0]) x->x_pipe = pipe; 
268
 
 
269
 
    return (void *)x;
270
 
 
271
 
}
272
 
 
273
 
 
274
 
 
275
 
#ifdef __cplusplus
276
 
extern "C"
277
 
{
278
 
#endif
279
 
 
280
 
 
281
 
void pdp_rawin_setup(void)
282
 
{
283
 
    int i;
284
 
 
285
 
    /* create a standard pd class: [pdp_rawin pipe type] */
286
 
    rawin_class = class_new(gensym("pdp_rawin"), (t_newmethod)rawin_new,
287
 
        (t_method)rawin_free, sizeof(t_rawin), 0, A_DEFSYMBOL, A_DEFSYMBOL, A_NULL);
288
 
 
289
 
    /* add global message handler */
290
 
    class_addmethod(rawin_class, (t_method)rawin_type, gensym("type"), A_SYMBOL, A_NULL);
291
 
    class_addmethod(rawin_class, (t_method)rawin_open, gensym("open"), A_DEFSYMBOL, A_NULL);
292
 
    class_addmethod(rawin_class, (t_method)rawin_close, gensym("close"), A_NULL);
293
 
 
294
 
 
295
 
}
296
 
 
297
 
#ifdef __cplusplus
298
 
}
299
 
#endif