24 #define FUSE_USE_VERSION 31    45 static unsigned fsel_open_mask;
    46 static const char fsel_hex_map[] = 
"0123456789ABCDEF";
    47 static struct fuse *fsel_fuse;  
    49 #define FSEL_CNT_MAX    10          52 static pthread_mutex_t fsel_mutex;      
    53 static unsigned fsel_poll_notify_mask;  
    54 static struct fuse_pollhandle *fsel_poll_handle[FSEL_FILES]; 
    55 static unsigned fsel_cnt[FSEL_FILES];   
    57 static int fsel_path_index(
const char *path)
    61         if (strlen(path) != 2 || path[0] != 
'/' || !isxdigit(ch) || islower(ch))
    63         return ch <= 
'9' ? ch - 
'0' : ch - 
'A' + 10;
    66 static int fsel_getattr(
const char *path, 
struct stat *stbuf,
    72         memset(stbuf, 0, 
sizeof(
struct stat));
    74         if (strcmp(path, 
"/") == 0) {
    75                 stbuf->st_mode = S_IFDIR | 0555;
    80         idx = fsel_path_index(path);
    84         stbuf->st_mode = S_IFREG | 0444;
    86         stbuf->st_size = fsel_cnt[idx];
    90 static int fsel_readdir(
const char *path, 
void *buf, 
fuse_fill_dir_t filler,
   101         if (strcmp(path, 
"/") != 0)
   104         for (i = 0; i < FSEL_FILES; i++) {
   105                 name[0] = fsel_hex_map[i];
   106                 filler(buf, name, NULL, 0, 0);
   114         int idx = fsel_path_index(path);
   118         if ((fi->
flags & O_ACCMODE) != O_RDONLY)
   120         if (fsel_open_mask & (1 << idx))
   122         fsel_open_mask |= (1 << idx);
   136 static int fsel_release(
const char *path, 
struct fuse_file_info *fi)
   142         fsel_open_mask &= ~(1 << idx);
   146 static int fsel_read(
const char *path, 
char *buf, 
size_t size, off_t offset,
   154         pthread_mutex_lock(&fsel_mutex);
   155         if (fsel_cnt[idx] < size)
   156                 size = fsel_cnt[idx];
   157         printf(
"READ   %X transferred=%zu cnt=%u\n", idx, size, fsel_cnt[idx]);
   158         fsel_cnt[idx] -= size;
   159         pthread_mutex_unlock(&fsel_mutex);
   161         memset(buf, fsel_hex_map[idx], size);
   166                      struct fuse_pollhandle *ph, 
unsigned *reventsp)
   168         static unsigned polled_zero;
   182                         fsel_fuse = cxt->
fuse;
   185         pthread_mutex_lock(&fsel_mutex);
   188                 struct fuse_pollhandle *oldph = fsel_poll_handle[idx];
   193                 fsel_poll_notify_mask |= (1 << idx);
   194                 fsel_poll_handle[idx] = ph;
   199                 printf(
"POLL   %X cnt=%u polled_zero=%u\n",
   200                        idx, fsel_cnt[idx], polled_zero);
   205         pthread_mutex_unlock(&fsel_mutex);
   211         .readdir        = fsel_readdir,
   213         .release        = fsel_release,
   218 static void *fsel_producer(
void *data)
   220         const struct timespec interval = { 0, 250000000 };
   221         unsigned idx = 0, nr = 1;
   228                 pthread_mutex_lock(&fsel_mutex);
   236                 for (i = 0, t = idx; i < nr;
   237                      i++, t = (t + FSEL_FILES / nr) % FSEL_FILES) {
   238                         if (fsel_cnt[t] == FSEL_CNT_MAX)
   242                         if (fsel_fuse && (fsel_poll_notify_mask & (1 << t))) {
   243                                 struct fuse_pollhandle *ph;
   245                                 printf(
"NOTIFY %X\n", t);
   246                                 ph = fsel_poll_handle[t];
   247                                 fuse_notify_poll(ph);
   249                                 fsel_poll_notify_mask &= ~(1 << t);
   250                                 fsel_poll_handle[t] = NULL;
   254                 idx = (idx + 1) % FSEL_FILES;
   258                 pthread_mutex_unlock(&fsel_mutex);
   260                 nanosleep(&interval, NULL);
   266 int main(
int argc, 
char *argv[])
   272         errno = pthread_mutex_init(&fsel_mutex, NULL);
   274                 perror(
"pthread_mutex_init");
   278         errno = pthread_attr_init(&attr);
   280                 perror(
"pthread_attr_init");
   284         errno = pthread_create(&producer, &attr, fsel_producer, NULL);
   286                 perror(
"pthread_create");
   290         ret = 
fuse_main(argc, argv, &fsel_oper, NULL);
   292         pthread_cancel(producer);
   293         pthread_join(producer, NULL);
 
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
#define fuse_main(argc, argv, op, private_data)
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
int(* getattr)(const char *, struct stat *, struct fuse_file_info *fi)
struct fuse_context * fuse_get_context(void)