00001
00021 #ifndef FILTER_H
00022 #define FILTER_H
00023
00024 #include <stdio.h>
00025 #include <iostream>
00026 #include <map>
00027 #include <list>
00028 #include <vector>
00029 #include <string>
00030 #include <queue>
00031 #include <unistd.h>
00032 #include <stdlib.h>
00033 #include <sstream>
00034
00035 #ifdef USE_PTHREAD
00036 #include <pthread.h>
00037 #endif
00038
00039 #include "buffer.h"
00040 #include "signalmanager.h"
00041 #include "common.h"
00042
00044 #define __EXIT_CHECK__ if(exit_check()){ break; }
00045
00047 namespace SMP{
00048
00049 class SMPKernel;
00050
00052 const int MAX_LEN = 128;
00053
00054 using namespace std;
00055
00056
00060 class property_item{
00061 public:
00063 string value;
00064
00068 bool runtime_ro;
00069
00076 string type;
00077
00078 property_item() { }
00079 property_item(string value, bool runtime_ro, string type="str")
00080 : value(value), runtime_ro(runtime_ro), type(type)
00081 { }
00082 };
00083
00084
00085
00090 class SMPFilter
00091 {
00092 friend class SMPKernel;
00093 public:
00094
00095 protected:
00096
00098 int id;
00099
00101 char name[MAX_LEN];
00102
00104
00105 int major;
00106 int minor;
00107
00109 int priority;
00110 bool realtime_on;
00111
00112
00113
00114
00116 int num_inport;
00118 int num_outport;
00119
00124 int *input_buffer;
00129 int *output_buffer;
00130
00131
00132
00134 SMPKernel *kernel;
00135
00137
00138
00139
00144 map<string, property_item> property;
00145
00146 #ifdef USE_PTHREAD
00147
00148
00149
00151
00152
00154
00155
00157
00158
00162 void signal_handler_wrapper();
00168 void signal_handler_wrapper_light();
00169
00171 pthread_mutex_t sig_queue_mutex;
00173 void signal_push(SMPSignal *sig);
00175 SMPSignal *signal_pop();
00177 bool signal_empty();
00178
00179
00181
00182
00184
00185
00187 queue<SMPSignal*> signal_queue;
00188
00190 pthread_mutex_t sig_mutex;
00193 pthread_cond_t sig_cond;
00194
00195
00196
00197
00199 int sig_num_inport;
00201 int sig_num_outport;
00202
00203
00208 int *sig_input_buffer;
00213 int *sig_output_buffer;
00214
00215
00216 #endif
00217
00229 #ifdef USE_PTHREAD
00230 void setup(int fid, const char *fname, int major_version, int minor_version,
00231 int *in_buf, int num_in, int *out_buf, int num_out,
00232 int *sig_in_buf, int sig_num_in, int *sig_out_buf, int sig_num_out);
00233 #else
00234 void setup(int fid, const char *fname, int major_version, int minor_version,
00235 int *in_buf, int num_in, int *out_buf, int num_out);
00236 #endif
00237
00238
00244 void set_input_buf(int input_port, int buf_id, port_model model = DATA_PORT);
00245
00250 void process_wrapper();
00251
00257 inline void set_rt_status(bool realtime);
00258
00259
00260 public:
00261
00265 SMPFilter(void);
00269 virtual ~SMPFilter(void);
00270
00271
00272 void get_env(int *argc, char ***argv);
00273
00274
00275
00276
00277
00278
00279
00287 ssize_t smp_read(int port_id, void *buff, size_t nbytes);
00295 ssize_t smp_write(int port_id, const void *buff, size_t nbytes);
00300 ssize_t smp_read_nonblock(int port_id, void *buff, size_t nbytes);
00305 ssize_t smp_write_nonblock(int port_id, const void *buff, size_t nbytes);
00306
00308 ssize_t smp_read_space(int port_id);
00310 ssize_t smp_write_space(int port_id);
00311
00313 void smp_yield();
00314
00322 ssize_t smp_p_read(int port_id, packet *p_buff, size_t npackets);
00323
00331 ssize_t smp_p_write(int port_id, const packet *p_buff, size_t npackets);
00336 ssize_t smp_p_read_nonblock(int port_id, packet *p_buff, size_t npackets);
00341 ssize_t smp_p_write_nonblock(int port_id, const packet *p_buff, size_t npackets);
00342
00348 bool smp_input_flush(int port_id, port_model model = DATA_PORT);
00354 bool smp_output_flush(int port_id, port_model model = DATA_PORT);
00355
00356 #ifdef USE_PTHREAD
00357
00358
00359
00365 int smp_signal(int port_id, SMPSignal *sig);
00366
00367 #endif
00368
00369
00370
00371
00372
00373
00378 inline bool inport_connected(port_model model = DATA_PORT);
00384 inline bool inport_connected(int port_id, port_model model = DATA_PORT);
00389 inline bool outport_connected(port_model model = DATA_PORT);
00395 inline bool outport_connected(int port_id, port_model model = DATA_PORT);
00396
00397
00398
00399
00400
00401
00405 void set_buf_status(port_type port, int port_id, int status);
00409 int get_buf_status(port_type port, int port_id);
00410
00411
00412
00413
00414
00423 template <class Type>
00424 inline bool get_property(const char *property_name, Type &data);
00429 inline string& get_property(const char *property_name);
00434 inline bool set_property(const char *property_name, const char *data);
00435
00436
00437
00438
00439
00443 bool exit_check(void);
00444
00448 void slim_exit(void);
00449
00453 inline bool is_realtime(void);
00454
00455
00460 void set_output_buf(int output_port, int buf_id, port_model model = DATA_PORT);
00461
00462
00463
00464
00465
00466
00470 void set_signal_timeout(int usec);
00471
00475 int get_signal_timeout(void);
00476
00482 SMPSignal *create_signal(SMP_SIGNAL_TYPE type = SMP_USEREVENT);
00483
00484
00485
00486
00487
00491 void unregister_watchdog();
00492
00493
00494
00495
00496
00497
00504 virtual int initialize();
00505
00512 virtual int finalize();
00513
00518 virtual int pause();
00519
00524 virtual int resume();
00525
00532 virtual int process()=0;
00533
00539 virtual int property_handler();
00540
00541 #ifdef USE_PTHREAD
00542
00547 virtual int signal_handler(SMPSignal *sig);
00548
00549 #endif
00550
00551
00552
00553
00554
00558 inline int get_id();
00559
00561 static void signal_handler_cleanup(void *arg);
00562
00563
00564
00565
00566
00567
00568
00569
00570 void set_watchdog(bool enabled);
00571 void set_signal_watchdog(bool enabled);
00572 };
00573
00574
00575
00576
00577
00578
00579
00580 bool SMPFilter::inport_connected(port_model model)
00581 {
00582 if(model == DATA_PORT){
00583 for(int i=0; i < num_inport; i++){
00584 if(input_buffer[i]==-1)
00585 return false;
00586 }
00587 }
00588 #ifdef USE_PTHREAD
00589 else if(model == SIGNAL_PORT){
00590 for(int i=0; i < sig_num_inport; i++){
00591 if(sig_input_buffer[i]==-1)
00592 return false;
00593 }
00594 }
00595 #endif
00596 return true;
00597 }
00598
00599 bool SMPFilter::inport_connected(int port_id, port_model model)
00600 {
00601 if(model == DATA_PORT){
00602 if(port_id >= num_inport)
00603 return false;
00604 return (input_buffer[port_id]==-1)?false:true;
00605 }
00606 #ifdef USE_PTHREAD
00607 else if(model == SIGNAL_PORT){
00608 if(port_id >= sig_num_inport)
00609 return false;
00610 return (sig_input_buffer[port_id]==-1)?false:true;
00611 }
00612 #endif
00613 return false;
00614 }
00615
00616 bool SMPFilter::outport_connected(port_model model)
00617 {
00618 if(model == DATA_PORT){
00619 for(int i=0; i < num_outport; i++){
00620 if(output_buffer[i]==-1)
00621 return false;
00622 }
00623 }
00624 #ifdef USE_PTHREAD
00625 else if(model == SIGNAL_PORT){
00626 for(int i=0; i < sig_num_outport; i++){
00627 if(sig_output_buffer[i]==-1)
00628 return false;
00629 }
00630 }
00631 #endif
00632 return true;
00633
00634 }
00635
00636 bool SMPFilter::outport_connected(int port_id, port_model model)
00637 {
00638 if(model == DATA_PORT){
00639 if(port_id >= num_outport)
00640 return false;
00641 return (output_buffer[port_id]==-1)?false:true;
00642 }
00643 #ifdef USE_PTHREAD
00644 else if(model == SIGNAL_PORT){
00645 if(port_id >= sig_num_outport)
00646 return false;
00647 return (sig_output_buffer[port_id]==-1)?false:true;
00648 }
00649 #endif
00650 return false;
00651 }
00652
00653 template <class Type>
00654 bool SMPFilter::get_property(const char *property_name, Type &data)
00655 {
00656 std::istringstream iss(property[property_name].value);
00657 return !(iss >> data).fail();
00658 }
00659
00660 string& SMPFilter::get_property(const char *property_name)
00661 {
00662 return property[property_name].value;
00663 }
00664
00665 bool SMPFilter::set_property(const char *property_name, const char *data)
00666 {
00667 if (property.find(property_name) != property.end()) {
00668 property[property_name].value = string(data);
00669 return true;
00670 }
00671
00672 return false;
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 int SMPFilter::get_id()
00692 {
00693 return id;
00694 }
00695
00696
00697 void SMPFilter::set_rt_status(bool realtime)
00698 {
00699 realtime_on = realtime;
00700 }
00701
00702 bool SMPFilter::is_realtime(void)
00703 {
00704 return realtime_on;
00705 }
00706
00707
00708 }
00709
00710 #endif