Я пишу автопоток мультиплексора в java, который должен читать пустое количество FileDescriptors. Чтобы прочитать дескрипторы файлов (или сокет и т. Д., У которых есть FileDescriptor), мне нужна точная душа, если у меня есть некоторые дескрипторы, и нет никакого события, не повторяйте все. А вот метод som в linux: select, poll. Я пытался использовать эти методы, но безуспешно. нативные коды:выбор и опрос не работают правильно
JNIEXPORT jint JNICALL Java_hu_ddsi_java_Native_JUnix_select(JNIEnv * env,jobject obj,jobjectArray fds,long timeout_s,long timeout_us)
{
int len = env->GetArrayLength(fds);
jclass cls = env->FindClass("java/io/FileDescriptor");
jfieldID fid = env->GetFieldID(cls, "fd", "I");
fd_set watch;
int buf = 0;
int max = 0;
for(int i=0;i < len;i++)
{
FD_SET(buf=(int) env->GetIntField(env->GetObjectArrayElement(fds, i),fid),&watch);
if(buf>max)
max = buf;
}
struct timeval *timeout = (timeval*) malloc(sizeof(struct timeval));
timeout->tv_sec = timeout_s;
timeout->tv_usec = timeout_us;
return select(max+1, &watch, NULL,NULL,timeout);
}
JNIEXPORT jint JNICALL Java_hu_ddsi_java_Native_JUnix_poll(JNIEnv * env,jobject obj,jlongArray pollfds,int timeout_ms)
{
unsigned int nfds = env->GetArrayLength(pollfds);
void* pointerfor = malloc(nfds*(sizeof(void*)));
for(int i=0;i < nfds;i++)
env->GetLongArrayRegion(pollfds,i,1,(jlong*) pointerfor+(sizeof(void*)*i));
return poll(((struct pollfd*)pointerfor), nfds,timeout_ms);
}
JNIEXPORT jlong JNICALL Java_hu_ddsi_java_Native_JUnix_pollfd(JNIEnv * env,jobject obj,jobject fd,jshort events,jshort revents)
{
jclass cls = env->FindClass("java/io/FileDescriptor");
jfieldID fid = env->GetFieldID(cls, "fd", "I");
struct pollfd *pfd = (pollfd*) malloc(sizeof(pollfd));
pfd->fd = env->GetIntField(fd,fid);
pfd->events = events;
pfd->revents = 0x0;
return (jlong) pfd;
}
JNIEXPORT jint JNICALL Java_hu_ddsi_java_Native_JUnix_pollfdfd(JNIEnv * env,jobject obj,jlong pfd_struct)
{
return ((struct pollfd*)pfd_struct)->fd;
}
JNIEXPORT jshort JNICALL Java_hu_ddsi_java_Native_JUnix_pollfdevents(JNIEnv * env,jobject obj,jlong pfd_struct)
{
return ((struct pollfd*)pfd_struct)->events;
}
JNIEXPORT jshort JNICALL Java_hu_ddsi_java_Native_JUnix_pollfdrevents(JNIEnv * env,jobject obj,jlong pfd_struct)
{
return ((struct pollfd*)pfd_struct)->revents;
}
И тест-код в Java:
public static void main(String args[]) throws Throwable
final FileInputStream is = new FileInputStream("/var/log/apache2/access.log");
long st = JUnix.pollfd(is.getFD(),(short)(JUnix.POLLIN|JUnix.POLLPRI));
int len = 0;
while(true)
{
System.out.println("ava:"+(len = is.available()));
for(int i=0;i < len;i++)
System.out.print((char) is.read());
// JUnix.select(new FileDescriptor[]{is.getFD()},5,0);
System.out.println("pollretval: "+JUnix.poll(new long[]{st},-1));
System.out.println("revent: "+JUnix.pollfdrevents(st));
System.out.println("pollfd: "+JUnix.pollfdfd(st));
}
}
И когда я просматриваю, я должен увидеть новые строки в терминале, но он будет заблокирован навсегда ... если я изменю таймаут, я поставлю теперь строки в моем терминале.
Иногда код сходить с ума и печать infintly:
ava:0
pollretval: 1
revent: 0
pollfd: 10
этот результат интересен, FileDescriptor таким же, произрастающий опрос вернулся с модифицированными Fd номерами, но в pollfd stuct Ревента поле ... он должен быть изменен, если произошло событие. Я тестировал, указатели находятся в хорошем месте (как показывает результат), а простой код C выполняет тот же результат (я не нашел InputStream.available, как метод в C для FD, поэтому я не вижу, сколько байтов доступно в поток, но его ожидание вечно)
Что я не так?
Если я дам положительный тайм-аут, его развязали, просыпайтесь бесконечно без ожидания. –